summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/ww8par6.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/ww8/ww8par6.cxx')
-rw-r--r--sw/source/filter/ww8/ww8par6.cxx6214
1 files changed, 6214 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx
new file mode 100644
index 000000000000..b298f3721b00
--- /dev/null
+++ b/sw/source/filter/ww8/ww8par6.cxx
@@ -0,0 +1,6214 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+#include <stdlib.h>
+#include <svl/itemiter.hxx>
+#include <rtl/tencinfo.h>
+
+
+#include <hintids.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/cntritem.hxx>
+#include <editeng/crsditem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/adjitem.hxx>
+#include <editeng/escpitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/akrnitem.hxx>
+#include <editeng/paperinf.hxx>
+#include <editeng/emphitem.hxx>
+#include <editeng/forbiddenruleitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/scriptspaceitem.hxx>
+#include <editeng/hngpnctitem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/blnkitem.hxx>
+#include <editeng/hyznitem.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <editeng/pgrditem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/charhiddenitem.hxx>
+#include <fmtpdsc.hxx>
+#include <node.hxx>
+#include <ndtxt.hxx> // SwTxtNode, siehe unten: JoinNode()
+#include <pam.hxx> // fuer SwPam
+#include <doc.hxx>
+#include <pagedesc.hxx> // class SwPageDesc
+#include <fmtanchr.hxx>
+#include <fmtcntnt.hxx>
+#include <fchrfmt.hxx>
+#include <fmthdft.hxx>
+#include <fmtclds.hxx>
+#include <fmtftntx.hxx>
+#include <frmatr.hxx>
+#include <section.hxx>
+#include <lineinfo.hxx>
+#include <fmtline.hxx>
+#include <txatbase.hxx>
+#include <fmtflcnt.hxx>
+#include <fmtclbl.hxx>
+#include <tgrditem.hxx>
+#include <hfspacingitem.hxx>
+#include <swtable.hxx>
+#include <fltini.hxx> //For CalculateFlySize
+#include "writerhelper.hxx"
+#include "writerwordglue.hxx"
+#include "ww8scan.hxx"
+#include "ww8par2.hxx" // class WW8RStyle, class WwAnchorPara
+#include "ww8graf.hxx"
+
+// OD 2004-05-18 #i27767#
+#include <fmtwrapinfluenceonobjpos.hxx>
+
+using namespace sw::util;
+using namespace sw::types;
+using namespace ::com::sun::star;
+using namespace nsHdFtFlags;
+
+//-----------------------------------------
+// diverses
+//-----------------------------------------
+
+#define MM_250 1417 // WW-Default fuer Hor. Seitenraender: 2.5 cm
+#define MM_200 1134 // WW-Default fuer u.Seitenrand: 2.0 cm
+
+
+BYTE lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap,
+ const WW8RStyle* pSty = 0, const WW8PLCFx_SEPX* pSep = 0);
+
+
+ColorData SwWW8ImplReader::GetCol(BYTE nIco)
+{
+ static const ColorData eSwWW8ColA[] =
+ {
+ COL_AUTO, COL_BLACK, COL_LIGHTBLUE, COL_LIGHTCYAN, COL_LIGHTGREEN,
+ COL_LIGHTMAGENTA, COL_LIGHTRED, COL_YELLOW, COL_WHITE, COL_BLUE,
+ COL_CYAN, COL_GREEN, COL_MAGENTA, COL_RED, COL_BROWN, COL_GRAY,
+ COL_LIGHTGRAY
+ };
+
+ return eSwWW8ColA[nIco];
+}
+
+inline sal_uInt32 MSRoundTweak(sal_uInt32 x)
+{
+ return x;
+}
+
+/***************************************************************************
+# Seiten - Attribute, die nicht ueber die Attribut-Verwaltung, sondern
+# ueber ...->HasSprm abgearbeitet werden
+# ( ausser OLST, dass weiterhin ein normales Attribut ist )
+#**************************************************************************/
+
+static short ReadSprm( const WW8PLCFx_SEPX* pSep, USHORT nId, short nDefaultVal )
+{
+ const BYTE* pS = pSep->HasSprm( nId ); // sprm da ?
+ short nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
+ return nVal;
+}
+
+static USHORT ReadUSprm( const WW8PLCFx_SEPX* pSep, USHORT nId, short nDefaultVal )
+{
+ const BYTE* pS = pSep->HasSprm( nId ); // sprm da ?
+ USHORT nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
+ return nVal;
+}
+
+static BYTE ReadBSprm( const WW8PLCFx_SEPX* pSep, USHORT nId, BYTE nDefaultVal )
+{
+ const BYTE* pS = pSep->HasSprm( nId ); // sprm da ?
+ BYTE nVal = ( pS ) ? SVBT8ToByte( pS ) : nDefaultVal;
+ return nVal;
+}
+
+void wwSection::SetDirection()
+{
+ //sprmSTextFlow
+ switch (maSep.wTextFlow)
+ {
+ default:
+ ASSERT(!this, "Unknown layout type");
+ case 0:
+ meDir=FRMDIR_HORI_LEFT_TOP;
+ break;
+ case 1:
+ meDir=FRMDIR_VERT_TOP_RIGHT;
+ break;
+ case 2:
+ //asian letters are not rotated, western are. We can't import
+ //bottom to top going left to right, we can't do this in
+ //pages, (in drawboxes we could partly hack it with a rotated
+ //drawing box, though not frame)
+ meDir=FRMDIR_VERT_TOP_RIGHT;
+ break;
+ case 3:
+ //asian letters are not rotated, western are. We can't import
+ meDir=FRMDIR_VERT_TOP_RIGHT;
+ break;
+ case 4:
+ //asian letters are rotated, western not. We can't import
+ meDir=FRMDIR_HORI_LEFT_TOP;
+ break;
+ }
+
+ sal_uInt8 nRTLPgn = maSep.fBiDi;
+ if ((meDir == FRMDIR_HORI_LEFT_TOP) && nRTLPgn)
+ meDir = FRMDIR_HORI_RIGHT_TOP;
+}
+
+bool wwSection::IsVertical() const
+{
+ if (meDir == FRMDIR_VERT_TOP_RIGHT || meDir == FRMDIR_VERT_TOP_LEFT)
+ return true;
+ return false;
+}
+
+/*
+ #113694#
+ This is something of festering mapping, I'm open to better ways of doing it,
+ but primarily the grid in writer is different to that in word. In writer the
+ grid elements are squares with ruby rows inbetween. While in word there is no
+ ruby stuff, and the elements are rectangles. By misusing the ruby row I can
+ handle distortions in one direction, but its all a bit of a mess:
+*/
+void SwWW8ImplReader::SetDocumentGrid(SwFrmFmt &rFmt, const wwSection &rSection)
+{
+ if (bVer67)
+ return;
+
+ rFmt.SetFmtAttr(SvxFrameDirectionItem(rSection.meDir, RES_FRAMEDIR));
+
+ SwTwips nTextareaHeight = rFmt.GetFrmSize().GetHeight();
+ const SvxULSpaceItem &rUL = ItemGet<SvxULSpaceItem>(rFmt, RES_UL_SPACE);
+ nTextareaHeight -= rUL.GetUpper();
+ nTextareaHeight -= rUL.GetLower();
+
+ SwTwips nTextareaWidth = rFmt.GetFrmSize().GetWidth();
+ const SvxLRSpaceItem &rLR = ItemGet<SvxLRSpaceItem>(rFmt, RES_LR_SPACE);
+ nTextareaWidth -= rLR.GetLeft();
+ nTextareaWidth -= rLR.GetRight();
+
+ if (rSection.IsVertical())
+ std::swap(nTextareaHeight, nTextareaWidth);
+
+ SwTextGridItem aGrid;
+ aGrid.SetDisplayGrid(false);
+ aGrid.SetPrintGrid(false);
+ SwTextGrid eType=GRID_NONE;
+
+ switch (rSection.maSep.clm)
+ {
+ case 0:
+ eType = GRID_NONE;
+ break;
+ default:
+ ASSERT(!this, "Unknown grid type");
+ case 3:
+ eType = GRID_LINES_CHARS;
+ aGrid.SetSnapToChars(sal_True);
+ break;
+ case 1:
+ eType = GRID_LINES_CHARS;
+ aGrid.SetSnapToChars(sal_False);
+ break;
+ case 2:
+ eType = GRID_LINES_ONLY;
+ break;
+ }
+
+ aGrid.SetGridType(eType);
+
+ // seem to not add external leading in word, or the character would run across
+ // two line in some cases.
+ if (eType != GRID_NONE)
+ rDoc.set(IDocumentSettingAccess::ADD_EXT_LEADING, false);
+
+ //force to set document as standard page mode
+ sal_Bool bSquaredMode = sal_False;
+ rDoc.SetDefaultPageMode( bSquaredMode );
+ aGrid.SetSquaredMode( bSquaredMode );
+
+ //sep.dyaLinePitch
+ sal_Int32 nLinePitch = rSection.maSep.dyaLinePitch;
+
+ //Get the size of word's default styles font
+ sal_uInt32 nCharWidth=240;
+ for (USHORT nI = 0; nI < pStyles->GetCount(); ++nI)
+ {
+ if (pCollA[nI].bValid && pCollA[nI].pFmt &&
+ pCollA[nI].GetWWStyleId() == 0)
+ {
+ nCharWidth = ItemGet<SvxFontHeightItem>(*(pCollA[nI].pFmt),
+ RES_CHRATR_CJK_FONTSIZE).GetHeight();
+ break;
+ }
+ }
+
+ //dxtCharSpace
+ if (rSection.maSep.dxtCharSpace)
+ {
+ UINT32 nCharSpace = rSection.maSep.dxtCharSpace;
+ //main lives in top 20 bits, and is signed.
+ INT32 nMain = (nCharSpace & 0xFFFFF000);
+ nMain/=0x1000;
+ nCharWidth += nMain*20;
+
+ int nFraction = (nCharSpace & 0x00000FFF);
+ nFraction = (nFraction*20)/0xFFF;
+ nCharWidth += nFraction;
+ }
+
+ aGrid.SetBaseWidth( writer_cast<sal_uInt16>(nCharWidth));
+ aGrid.SetLines(writer_cast<sal_uInt16>(nTextareaHeight/nLinePitch));
+ aGrid.SetBaseHeight(writer_cast<sal_uInt16>(nLinePitch));
+
+ // ruby height is not supported in ww8
+ //sal_Int32 nRubyHeight = nLinePitch - nCharWidth;
+ //if (nRubyHeight < 0)
+ // nRubyHeight = 0;
+ sal_Int32 nRubyHeight = 0;
+ aGrid.SetRubyHeight(writer_cast<sal_uInt16>(nRubyHeight));
+
+ rFmt.SetFmtAttr(aGrid);
+}
+
+void SwWW8ImplReader::Read_ParaBiDi(USHORT, const BYTE* pData, short nLen)
+{
+ if( nLen < 0 )
+ pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_FRAMEDIR);
+ else
+ {
+ SvxFrameDirection eDir =
+ *pData ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP;
+ NewAttr(SvxFrameDirectionItem(eDir, RES_FRAMEDIR));
+ }
+}
+
+bool wwSectionManager::SetCols(SwFrmFmt &rFmt, const wwSection &rSection,
+ sal_uInt32 nNettoWidth) const
+{
+ //sprmSCcolumns - Anzahl der Spalten - 1
+ sal_Int16 nCols = rSection.NoCols();
+
+ if (nCols < 2)
+ return false; // keine oder bloedsinnige Spalten
+
+ SwFmtCol aCol; // Erzeuge SwFmtCol
+
+ //sprmSDxaColumns - Default-Abstand 1.25 cm
+ sal_Int32 nColSpace = rSection.StandardColSeperation();
+
+ // sprmSLBetween
+ if (rSection.maSep.fLBetween)
+ {
+ aCol.SetLineAdj(COLADJ_TOP); // Line
+ aCol.SetLineHeight(100);
+ aCol.SetLineColor(Color(COL_BLACK));
+ aCol.SetLineWidth(1);
+ }
+
+ aCol.Init(nCols, writer_cast<USHORT>(nColSpace),
+ writer_cast<USHORT>(nNettoWidth));
+
+ // sprmSFEvenlySpaced
+ if (!rSection.maSep.fEvenlySpaced)
+ {
+ aCol._SetOrtho(false);
+ int nIdx = 1;
+ for (USHORT i = 0; i < nCols; i++ )
+ {
+ SwColumn* pCol = aCol.GetColumns()[i];
+ sal_Int32 nLeft = rSection.maSep.rgdxaColumnWidthSpacing[nIdx-1]/2;
+ sal_Int32 nRight = rSection.maSep.rgdxaColumnWidthSpacing[nIdx+1]/2;
+ sal_Int32 nWishWidth = rSection.maSep.rgdxaColumnWidthSpacing[nIdx]
+ + nLeft + nRight;
+ pCol->SetWishWidth(writer_cast<USHORT>(nWishWidth));
+ pCol->SetLeft(writer_cast<USHORT>(nLeft));
+ pCol->SetRight(writer_cast<USHORT>(nRight));
+ nIdx += 2;
+ }
+ aCol.SetWishWidth(writer_cast<USHORT>(nNettoWidth));
+ }
+ rFmt.SetFmtAttr(aCol);
+ return true;
+}
+
+void wwSectionManager::SetLeftRight(wwSection &rSection)
+{
+ // 3. LR-Raender
+ sal_uInt32 nWWLe = MSRoundTweak(rSection.maSep.dxaLeft);
+ sal_uInt32 nWWRi = MSRoundTweak(rSection.maSep.dxaRight);
+ sal_uInt32 nWWGu = rSection.maSep.dzaGutter;
+
+ /*
+ fRTLGutter is set if the gutter is on the right, the gutter is otherwise
+ placed on the left unless the global dop options are to put it on top, that
+ case is handled in GetPageULData.
+ */
+ if (rSection.maSep.fRTLGutter)
+ nWWRi += nWWGu;
+ else if (!mrReader.pWDop->iGutterPos)
+ nWWLe += nWWGu;
+
+ // Left / Right
+ if ((rSection.nPgWidth - nWWLe - nWWRi) < MINLAY)
+ {
+ /*
+ There are some label templates which are "broken", they specify
+ margins which make no sense e.g. Left 16.10cm, Right 16.10cm. So the
+ space left between the margins is less than 0 In word the left margin
+ is honoured and if the right margin would be past the left margin is
+ left at the left margin position.
+
+ Now this will work fine for importing, layout and exporting, *but* the
+ page layout dialog has a hardcoded minimum page width of 0.5cm so it
+ will report a different value than what is actually being used. i.e.
+ it will add up the values to give a wider page than is actually being
+ used.
+ */
+ nWWRi = rSection.nPgWidth - nWWLe - MINLAY;
+ }
+
+ rSection.nPgLeft = nWWLe;
+ rSection.nPgRight = nWWRi;
+}
+
+void wwSectionManager::SetPage(SwPageDesc &rInPageDesc, SwFrmFmt &rFmt,
+ const wwSection &rSection, bool bIgnoreCols) const
+{
+ // 1. Orientierung
+ rInPageDesc.SetLandscape(rSection.IsLandScape());
+
+ // 2. Papiergroesse
+ SwFmtFrmSize aSz( rFmt.GetFrmSize() );
+ aSz.SetWidth(rSection.GetPageWidth());
+ aSz.SetHeight(SvxPaperInfo::GetSloppyPaperDimension(rSection.GetPageHeight()));
+ rFmt.SetFmtAttr(aSz);
+
+ rFmt.SetFmtAttr(
+ SvxLRSpaceItem(rSection.GetPageLeft(), rSection.GetPageRight(), 0, 0, RES_LR_SPACE));
+
+ if (!bIgnoreCols)
+ SetCols(rFmt, rSection, rSection.GetTextAreaWidth());
+}
+
+USHORT lcl_MakeSafeNegativeSpacing(USHORT nIn)
+{
+ if (nIn > SHRT_MAX)
+ nIn = 0;
+ return nIn;
+}
+
+void SwWW8ImplReader::SetPageBorder(SwFrmFmt &rFmt, const wwSection &rSection) const
+{
+ if (!IsBorder(rSection.brc))
+ return;
+
+ SfxItemSet aSet(rFmt.GetAttrSet());
+ short aSizeArray[5]={0};
+ SetFlyBordersShadow(aSet, rSection.brc, &aSizeArray[0]);
+ SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(aSet, RES_LR_SPACE));
+ SvxULSpaceItem aUL(ItemGet<SvxULSpaceItem>(aSet, RES_UL_SPACE));
+
+ SvxBoxItem aBox(ItemGet<SvxBoxItem>(aSet, RES_BOX));
+ short aOriginalBottomMargin = aBox.GetDistance(BOX_LINE_BOTTOM);
+
+ if (rSection.maSep.pgbOffsetFrom == 1)
+ {
+ USHORT nDist;
+ if (aBox.GetLeft())
+ {
+ nDist = aBox.GetDistance(BOX_LINE_LEFT);
+ aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aLR.GetLeft() - nDist)), BOX_LINE_LEFT);
+ aSizeArray[WW8_LEFT] =
+ aSizeArray[WW8_LEFT] - nDist + aBox.GetDistance(BOX_LINE_LEFT);
+ }
+
+ if (aBox.GetRight())
+ {
+ nDist = aBox.GetDistance(BOX_LINE_RIGHT);
+ aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aLR.GetRight() - nDist)), BOX_LINE_RIGHT);
+ aSizeArray[WW8_RIGHT] =
+ aSizeArray[WW8_RIGHT] - nDist + aBox.GetDistance(BOX_LINE_RIGHT);
+ }
+
+ if (aBox.GetTop())
+ {
+ nDist = aBox.GetDistance(BOX_LINE_TOP);
+ aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aUL.GetUpper() - nDist)), BOX_LINE_TOP);
+ aSizeArray[WW8_TOP] =
+ aSizeArray[WW8_TOP] - nDist + aBox.GetDistance(BOX_LINE_TOP);
+ }
+
+ if (aBox.GetBottom())
+ {
+ nDist = aBox.GetDistance(BOX_LINE_BOTTOM);
+ aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aUL.GetLower() - nDist)), BOX_LINE_BOTTOM);
+ aSizeArray[WW8_BOT] =
+ aSizeArray[WW8_BOT] - nDist + aBox.GetDistance(BOX_LINE_BOTTOM);
+ }
+
+ aSet.Put(aBox);
+ }
+
+ if (aBox.GetLeft())
+ aLR.SetLeft(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aLR.GetLeft() - aSizeArray[WW8_LEFT])));
+ if (aBox.GetRight())
+ aLR.SetRight(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aLR.GetRight() - aSizeArray[WW8_RIGHT])));
+ if (aBox.GetTop())
+ aUL.SetUpper(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aUL.GetUpper() - aSizeArray[WW8_TOP])));
+ if (aBox.GetBottom())
+ {
+ //#i30088# and #i30074# - do a final sanity check on
+ //bottom value. Do not allow a resulting zero if bottom
+ //Border margin value was not originally zero.
+ if(aUL.GetLower() != 0)
+ aUL.SetLower(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aUL.GetLower() - aSizeArray[WW8_BOT])));
+ else
+ aUL.SetLower(lcl_MakeSafeNegativeSpacing(static_cast<USHORT>(aOriginalBottomMargin - aSizeArray[WW8_BOT])));
+ }
+
+ aSet.Put(aLR);
+ aSet.Put(aUL);
+ rFmt.SetFmtAttr(aSet);
+}
+
+void wwSectionManager::GetPageULData(const wwSection &rSection, bool bFirst,
+ wwSectionManager::wwULSpaceData& rData) const
+{
+ sal_Int32 nWWUp = rSection.maSep.dyaTop;
+ sal_Int32 nWWLo = rSection.maSep.dyaBottom;
+ sal_uInt32 nWWHTop = rSection.maSep.dyaHdrTop;
+ sal_uInt32 nWWFBot = rSection.maSep.dyaHdrBottom;
+
+ /*
+ If there is gutter in 97+ and the dop says put it on top then get the
+ gutter distance and set it to the top margin. When we are "two pages
+ in one" the gutter is put at the top of odd pages, and bottom of
+ even pages, something we cannot do. So we will put it on top of all
+ pages, that way the pages are at least the right size.
+ */
+ if (
+ (!mrReader.bVer67 && mrReader.pWDop->iGutterPos &&
+ rSection.maSep.fRTLGutter)
+ )
+ {
+ nWWUp += rSection.maSep.dzaGutter;
+ }
+
+ if( bFirst )
+ rData.bHasHeader = (rSection.maSep.grpfIhdt & WW8_HEADER_FIRST) !=0;
+ else
+ {
+ rData.bHasHeader = (rSection.maSep.grpfIhdt &
+ (WW8_HEADER_EVEN | WW8_HEADER_ODD)) != 0;
+ }
+
+ if( rData.bHasHeader )
+ {
+ rData.nSwUp = nWWHTop; // Header -> umrechnen
+ // --> CMC, OD 2004-06-18 #i19922# - correction:
+ // consider that <nWWUp> can be negative, compare only if it's positive
+ if ( nWWUp > 0 &&
+ static_cast<sal_uInt32>(abs(nWWUp)) >= nWWHTop )
+ rData.nSwHLo = nWWUp - nWWHTop;
+ else
+ rData.nSwHLo = 0;
+
+ // --> OD 2004-06-18 #i19922# - minimum page header height is now 1mm
+ // use new constant <cMinHdFtHeight>
+ if (rData.nSwHLo < sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight))
+ rData.nSwHLo = sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight);
+ }
+ else // kein Header -> Up einfach uebernehmen
+ rData.nSwUp = Abs(nWWUp);
+
+ if( bFirst )
+ rData.bHasFooter = (rSection.maSep.grpfIhdt & WW8_FOOTER_FIRST) !=0;
+ else
+ {
+ rData.bHasFooter = (rSection.maSep.grpfIhdt &
+ (WW8_FOOTER_EVEN | WW8_FOOTER_ODD)) != 0;
+ }
+
+ if( rData.bHasFooter )
+ {
+ rData.nSwLo = nWWFBot; // Footer -> Umrechnen
+ // --> CMC, OD 2004-06-18 #i19922# - correction:
+ // consider that <nWWLo> can be negative, compare only if it's positive
+ if ( nWWLo > 0 &&
+ static_cast<sal_uInt32>(abs(nWWLo)) >= nWWFBot )
+ rData.nSwFUp = nWWLo - nWWFBot;
+ else
+ rData.nSwFUp = 0;
+
+ // --> OD 2004-06-18 #i19922# - minimum page header height is now 1mm
+ // use new constant <cMinHdFtHeight>
+ if (rData.nSwFUp < sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight))
+ rData.nSwFUp = sal::static_int_cast< sal_uInt32 >(cMinHdFtHeight);
+ }
+ else // kein Footer -> Lo einfach uebernehmen
+ rData.nSwLo = Abs(nWWLo);
+}
+
+void wwSectionManager::SetPageULSpaceItems(SwFrmFmt &rFmt,
+ wwSectionManager::wwULSpaceData& rData, const wwSection &rSection) const
+{
+ if (rData.bHasHeader) // ... und Header-Lower setzen
+ {
+ //Kopfzeilenhoehe minimal sezten
+ if (SwFrmFmt* pHdFmt = (SwFrmFmt*)rFmt.GetHeader().GetHeaderFmt())
+ {
+ SvxULSpaceItem aHdUL(pHdFmt->GetULSpace());
+ if (!rSection.IsFixedHeightHeader()) //normal
+ {
+ pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwHLo));
+ // --> OD 2004-06-18 #i19922# - minimum page header height is now 1mm
+ // use new constant <cMinHdFtHeight>
+ aHdUL.SetLower( writer_cast<USHORT>(rData.nSwHLo - cMinHdFtHeight) );
+ pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
+ RES_HEADER_FOOTER_EAT_SPACING, true));
+ }
+ else
+ {
+ // --> OD 2005-05-20 #i48832# - set correct spacing between
+ // header and body.
+ const SwTwips nHdLowerSpace( Abs(rSection.maSep.dyaTop) - rData.nSwUp - rData.nSwHLo );
+ pHdFmt->SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE, 0, rData.nSwHLo + nHdLowerSpace));
+ aHdUL.SetLower( static_cast< USHORT >(nHdLowerSpace) );
+ // <--
+ pHdFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
+ RES_HEADER_FOOTER_EAT_SPACING, false));
+ }
+ pHdFmt->SetFmtAttr(aHdUL);
+ }
+ }
+
+ if (rData.bHasFooter) // ... und Footer-Upper setzen
+ {
+ if (SwFrmFmt* pFtFmt = (SwFrmFmt*)rFmt.GetFooter().GetFooterFmt())
+ {
+ SvxULSpaceItem aFtUL(pFtFmt->GetULSpace());
+ if (!rSection.IsFixedHeightFooter()) //normal
+ {
+ pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_MIN_SIZE, 0, rData.nSwFUp));
+ // --> OD 2004-06-18 #i19922# - minimum page header height is now 1mm
+ // use new constant <cMinHdFtHeight>
+ aFtUL.SetUpper( writer_cast<USHORT>(rData.nSwFUp - cMinHdFtHeight) );
+ pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
+ RES_HEADER_FOOTER_EAT_SPACING, true));
+ }
+ else
+ {
+ // --> OD 2005-05-20 #i48832# - set correct spacing between
+ // footer and body.
+ const SwTwips nFtUpperSpace( Abs(rSection.maSep.dyaBottom) - rData.nSwLo - rData.nSwFUp );
+ pFtFmt->SetFmtAttr(SwFmtFrmSize(ATT_FIX_SIZE, 0, rData.nSwFUp + nFtUpperSpace));
+ aFtUL.SetUpper( static_cast< USHORT >(nFtUpperSpace) );
+ // <--
+ pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
+ RES_HEADER_FOOTER_EAT_SPACING, false));
+ }
+ pFtFmt->SetFmtAttr(aFtUL);
+ }
+ }
+
+ SvxULSpaceItem aUL(writer_cast<USHORT>(rData.nSwUp),
+ writer_cast<USHORT>(rData.nSwLo), RES_UL_SPACE);
+ rFmt.SetFmtAttr(aUL);
+}
+
+SwSectionFmt *wwSectionManager::InsertSection(
+ SwPaM& rMyPaM, wwSection &rSection)
+{
+ SwSectionData aSection( CONTENT_SECTION,
+ mrReader.rDoc.GetUniqueSectionName() );
+
+ SfxItemSet aSet( mrReader.rDoc.GetAttrPool(), aFrmFmtSetRange );
+
+ sal_uInt8 nRTLPgn = maSegments.empty() ? 0 : maSegments.back().IsBiDi();
+ aSet.Put(SvxFrameDirectionItem(
+ nRTLPgn ? FRMDIR_HORI_RIGHT_TOP : FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
+
+ if (2 == mrReader.pWDop->fpc)
+ aSet.Put( SwFmtFtnAtTxtEnd(FTNEND_ATTXTEND));
+ if (0 == mrReader.pWDop->epc)
+ aSet.Put( SwFmtEndAtTxtEnd(FTNEND_ATTXTEND));
+
+ aSection.SetProtectFlag(SectionIsProtected(rSection));
+
+ rSection.mpSection =
+ mrReader.rDoc.InsertSwSection( rMyPaM, aSection, 0, & aSet );
+ ASSERT(rSection.mpSection, "section not inserted!");
+ if (!rSection.mpSection)
+ return 0;
+
+ SwPageDesc *pPage = 0;
+ mySegrIter aEnd = maSegments.rend();
+ for (mySegrIter aIter = maSegments.rbegin(); aIter != aEnd; ++aIter)
+ {
+ if (0 != (pPage = aIter->mpPage))
+ break;
+ }
+
+ ASSERT(pPage, "no page outside this section!");
+
+ if (!pPage)
+ pPage = &mrReader.rDoc._GetPageDesc(0);
+
+ if (!pPage)
+ return 0;
+
+ SwSectionFmt *pFmt = rSection.mpSection->GetFmt();
+ ASSERT(pFmt, "impossible");
+ if (!pFmt)
+ return 0;
+
+ SwFrmFmt& rFmt = pPage->GetMaster();
+ const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
+ long nPageLeft = rLR.GetLeft();
+ long nPageRight = rLR.GetRight();
+ long nSectionLeft = rSection.GetPageLeft() - nPageLeft;
+ long nSectionRight = rSection.GetPageRight() - nPageRight;
+ if ((nSectionLeft != 0) || (nSectionRight != 0))
+ {
+ SvxLRSpaceItem aLR(nSectionLeft, nSectionRight, 0, 0, RES_LR_SPACE);
+ pFmt->SetFmtAttr(aLR);
+ }
+
+ SetCols(*pFmt, rSection, rSection.GetTextAreaWidth());
+ return pFmt;
+}
+
+void SwWW8ImplReader::HandleLineNumbering(const wwSection &rSection)
+{
+ // check if Line Numbering must be activated or resetted
+ if (mbNewDoc && rSection.maSep.nLnnMod)
+ {
+ // restart-numbering-mode: 0 per page, 1 per section, 2 never restart
+ bool bRestartLnNumPerSection = (1 == rSection.maSep.lnc);
+
+ if (bNoLnNumYet)
+ {
+ SwLineNumberInfo aInfo( rDoc.GetLineNumberInfo() );
+
+ aInfo.SetPaintLineNumbers(true);
+
+ aInfo.SetRestartEachPage(rSection.maSep.lnc == 0);
+
+ aInfo.SetPosFromLeft(writer_cast<USHORT>(rSection.maSep.dxaLnn));
+
+ //Paint only for every n line
+ aInfo.SetCountBy(rSection.maSep.nLnnMod);
+
+ // to be defaulted features ( HARDCODED in MS Word 6,7,8,9 )
+ aInfo.SetCountBlankLines(true);
+ aInfo.SetCountInFlys(false);
+ aInfo.SetPos( LINENUMBER_POS_LEFT );
+ SvxNumberType aNumType; // this sets SVX_NUM_ARABIC per default
+ aInfo.SetNumType( aNumType );
+
+ rDoc.SetLineNumberInfo( aInfo );
+ bNoLnNumYet = false;
+ }
+
+ if (
+ (0 < rSection.maSep.lnnMin) ||
+ (bRestartLnNumPerSection && !bNoLnNumYet)
+ )
+ {
+ SwFmtLineNumber aLN;
+ if (const SwFmtLineNumber* pLN
+ = (const SwFmtLineNumber*)GetFmtAttr(RES_LINENUMBER))
+ {
+ aLN.SetCountLines( pLN->IsCount() );
+ }
+ aLN.SetStartValue(1 + rSection.maSep.lnnMin);
+ NewAttr(aLN);
+ pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LINENUMBER);
+ }
+ bNoLnNumYet = false;
+ }
+}
+
+wwSection::wwSection(const SwPosition &rPos) : maStart(rPos.nNode),
+ mpSection(0), mpTitlePage(0), mpPage(0), meDir(FRMDIR_HORI_LEFT_TOP),
+ nPgWidth(SvxPaperInfo::GetPaperSize(PAPER_A4).Width()),
+ nPgLeft(MM_250), nPgRight(MM_250), mnBorders(0), mbHasFootnote(false)
+{
+}
+
+void wwSectionManager::SetNumberingType(const wwSection &rNewSection,
+ SwPageDesc &rPageDesc) const
+{
+ // Seitennummernformat speichern
+ static const SvxExtNumType aNumTyp[5] =
+ {
+ SVX_NUM_ARABIC, SVX_NUM_ROMAN_UPPER, SVX_NUM_ROMAN_LOWER,
+ SVX_NUM_CHARS_UPPER_LETTER_N, SVX_NUM_CHARS_LOWER_LETTER_N
+ };
+
+ SvxNumberType aType;
+ aType.SetNumberingType( static_cast< sal_Int16 >(aNumTyp[rNewSection.maSep.nfcPgn]) );
+ rPageDesc.SetNumType(aType);
+}
+
+// Bei jedem Abschnittswechsel ( auch am Anfang eines Dokuments ) wird
+// CreateSep gerufen, dass dann den / die Pagedesc(s) erzeugt und
+// mit Attributen un KF-Texten fuellt.
+// Dieses Vorgehen ist noetig geworden, da die UEbersetzung der verschiedenen
+// Seiten-Attribute zu stark verflochten ist.
+void wwSectionManager::CreateSep(const long nTxtPos, bool /*bMustHaveBreak*/)
+{
+ /*
+ #i1909# #100688# section/page breaks should not occur in tables or subpage
+ elements like frames. Word itself ignores them in this case. The bug is
+ more likely that this filter created such documents in the past!
+ */
+ if (mrReader.nInTable || mrReader.bTxbxFlySection || mrReader.InLocalApo())
+ return;
+
+ WW8PLCFx_SEPX* pSep = mrReader.pPlcxMan->GetSepPLCF();
+ ASSERT(pSep, "impossible!");
+ if (!pSep)
+ return;
+
+ ww::WordVersion eVer = mrReader.GetFib().GetFIBVersion();
+
+ // M.M. Create a linked section if the WkbPLCF
+ // has an entry for one at this cp
+ WW8PLCFspecial* pWkb = mrReader.pPlcxMan->GetWkbPLCF();
+ if (pWkb && pWkb->SeekPosExact(nTxtPos) &&
+ pWkb->Where() == nTxtPos)
+ {
+ void* pData;
+ WW8_CP nTest;
+ pWkb->Get(nTest, pData);
+ String sSectionName = mrReader.aLinkStringMap[SVBT16ToShort( ((WW8_WKB*)pData)->nLinkId) ];
+ mrReader.ConvertFFileName(sSectionName, sSectionName);
+ SwSectionData aSection(FILE_LINK_SECTION, sSectionName);
+ aSection.SetLinkFileName( sSectionName );
+ aSection.SetProtectFlag(true);
+ // --> CMC, OD 2004-06-18 #i19922# improvement:
+ // return value of method <Insert> not used.
+ mrReader.rDoc.InsertSwSection(*mrReader.pPaM, aSection, 0, 0, false);
+ }
+
+ wwSection aLastSection(*mrReader.pPaM->GetPoint());
+ if (!maSegments.empty())
+ aLastSection = maSegments.back();
+
+ //Here
+ USHORT nLIdx = ( ( mrReader.pWwFib->lid & 0xff ) == 0x9 ) ? 1 : 0;
+
+ //BEGIN read section values
+ wwSection aNewSection(*mrReader.pPaM->GetPoint());
+
+ static const USHORT aVer2Ids0[] =
+ {
+ /*sprmSBkc*/ 117,
+ /*sprmSFTitlePage*/ 118,
+ /*sprmSNfcPgn*/ 122,
+ /*sprmSCcolumns*/ 119,
+ /*sprmSDxaColumns*/ 120,
+ /*sprmSLBetween*/ 133
+ };
+
+ static const USHORT aVer67Ids0[] =
+ {
+ /*sprmSBkc*/ 142,
+ /*sprmSFTitlePage*/ 143,
+ /*sprmSNfcPgn*/ 147,
+ /*sprmSCcolumns*/ 144,
+ /*sprmSDxaColumns*/ 145,
+ /*sprmSLBetween*/ 158
+ };
+
+ static const USHORT aVer8Ids0[] =
+ {
+ /*sprmSBkc*/ 0x3009,
+ /*sprmSFTitlePage*/ 0x300A,
+ /*sprmSNfcPgn*/ 0x300E,
+ /*sprmSCcolumns*/ 0x500B,
+ /*sprmSDxaColumns*/ 0x900C,
+ /*sprmSLBetween*/ 0x3019
+ };
+
+ const USHORT* pIds = eVer <= ww::eWW2 ? aVer2Ids0 : eVer <= ww::eWW7 ? aVer67Ids0 : aVer8Ids0;
+
+ if (!maSegments.empty())
+ {
+ // Type of break: break codes are:
+ // 0 No break
+ // 1 New column
+ // 2 New page
+ // 3 Even page
+ // 4 Odd page
+ if (const BYTE* pSprmBkc = pSep->HasSprm(pIds[0]))
+ aNewSection.maSep.bkc = *pSprmBkc;
+ }
+
+ // Has a table page
+ aNewSection.maSep.fTitlePage =
+ (0 != ReadBSprm( pSep, pIds[1], 0 ));
+
+ // sprmSNfcPgn
+ aNewSection.maSep.nfcPgn = ReadBSprm( pSep, pIds[2], 0 );
+ if (aNewSection.maSep.nfcPgn > 4)
+ aNewSection.maSep.nfcPgn = 0;
+
+ aNewSection.maSep.fUnlocked = eVer > ww::eWW2 ? ReadBSprm(pSep, (eVer <= ww::eWW7 ? 139 : 0x3006), 0 ) : 0;
+
+ // sprmSFBiDi
+ aNewSection.maSep.fBiDi = eVer >= ww::eWW8 ? ReadBSprm(pSep, 0x3228, 0) : 0;
+
+ aNewSection.maSep.ccolM1 = ReadSprm(pSep, pIds[3], 0 );
+
+ //sprmSDxaColumns - Default-Abstand 1.25 cm
+ aNewSection.maSep.dxaColumns = ReadUSprm( pSep, pIds[4], 708 );
+
+ // sprmSLBetween
+ aNewSection.maSep.fLBetween = ReadBSprm(pSep, pIds[5], 0 );
+
+ if (eVer >= ww::eWW6)
+ {
+ // sprmSFEvenlySpaced
+ aNewSection.maSep.fEvenlySpaced =
+ ReadBSprm(pSep, (eVer <= ww::eWW7 ? 138 : 0x3005), 1) ? true : false;
+
+ if (aNewSection.maSep.ccolM1 > 0 && !aNewSection.maSep.fEvenlySpaced)
+ {
+ aNewSection.maSep.rgdxaColumnWidthSpacing[0] = 0;
+ int nCols = aNewSection.maSep.ccolM1 + 1;
+ int nIdx = 0;
+ for (int i = 0; i < nCols; ++i)
+ {
+ //sprmSDxaColWidth
+ const BYTE* pSW = pSep->HasSprm( (eVer <= ww::eWW7 ? 136 : 0xF203), BYTE( i ) );
+
+ ASSERT( pSW, "+Sprm 136 (bzw. 0xF203) (ColWidth) fehlt" );
+ sal_uInt16 nWidth = pSW ? SVBT16ToShort(pSW + 1) : 1440;
+
+ aNewSection.maSep.rgdxaColumnWidthSpacing[++nIdx] = nWidth;
+
+ if (i < nCols-1)
+ {
+ //sprmSDxaColSpacing
+ const BYTE* pSD = pSep->HasSprm( (eVer <= ww::eWW7 ? 137 : 0xF204), BYTE( i ) );
+
+ ASSERT( pSD, "+Sprm 137 (bzw. 0xF204) (Colspacing) fehlt" );
+ if( pSD )
+ {
+ nWidth = SVBT16ToShort(pSD + 1);
+ aNewSection.maSep.rgdxaColumnWidthSpacing[++nIdx] = nWidth;
+ }
+ }
+ }
+ }
+ }
+
+ static const USHORT aVer2Ids1[] =
+ {
+ /*sprmSBOrientation*/ 137,
+ /*sprmSXaPage*/ 139,
+ /*sprmSYaPage*/ 140,
+ /*sprmSDxaLeft*/ 141,
+ /*sprmSDxaRight*/ 142,
+ /*sprmSDzaGutter*/ 145,
+ /*sprmSFPgnRestart*/ 125,
+ /*sprmSPgnStart*/ 136,
+ /*sprmSDmBinFirst*/ 115,
+ /*sprmSDmBinOther*/ 116
+ };
+
+ static const USHORT aVer67Ids1[] =
+ {
+ /*sprmSBOrientation*/ 162,
+ /*sprmSXaPage*/ 164,
+ /*sprmSYaPage*/ 165,
+ /*sprmSDxaLeft*/ 166,
+ /*sprmSDxaRight*/ 167,
+ /*sprmSDzaGutter*/ 170,
+ /*sprmSFPgnRestart*/ 150,
+ /*sprmSPgnStart*/ 161,
+ /*sprmSDmBinFirst*/ 140,
+ /*sprmSDmBinOther*/ 141
+ };
+
+ static const USHORT aVer8Ids1[] =
+ {
+ /*sprmSBOrientation*/ 0x301d,
+ /*sprmSXaPage*/ 0xB01F,
+ /*sprmSYaPage*/ 0xB020,
+ /*sprmSDxaLeft*/ 0xB021,
+ /*sprmSDxaRight*/ 0xB022,
+ /*sprmSDzaGutter*/ 0xB025,
+ /*sprmSFPgnRestart*/ 0x3011,
+ /*sprmSPgnStart*/ 0x501C,
+ /*sprmSDmBinFirst*/ 0x5007,
+ /*sprmSDmBinOther*/ 0x5008
+ };
+
+ pIds = eVer <= ww::eWW2 ? aVer2Ids1 : eVer <= ww::eWW7 ? aVer67Ids1 : aVer8Ids1;
+
+ // 1. Orientierung
+ aNewSection.maSep.dmOrientPage = ReadBSprm(pSep, pIds[0], 0);
+
+ // 2. Papiergroesse
+ aNewSection.maSep.xaPage = ReadUSprm(pSep, pIds[1], lLetterWidth);
+ aNewSection.nPgWidth = SvxPaperInfo::GetSloppyPaperDimension(aNewSection.maSep.xaPage);
+
+ aNewSection.maSep.yaPage = ReadUSprm(pSep, pIds[2], lLetterHeight);
+
+ // 3. LR-Raender
+ static const USHORT nLef[] = { MM_250, 1800 };
+ static const USHORT nRig[] = { MM_250, 1800 };
+
+ aNewSection.maSep.dxaLeft = ReadUSprm( pSep, pIds[3], nLef[nLIdx]);
+ aNewSection.maSep.dxaRight = ReadUSprm( pSep, pIds[4], nRig[nLIdx]);
+
+ //#110175# 2pages in 1sheet hackery ?
+ //#i31806# but only swap if 2page in 1sheet is enabled.
+ // its not clear if dmOrientPage is the correct member to
+ // decide on this but I am not about to 2nd guess cmc.
+ if(mrReader.pWDop->doptypography.f2on1 &&
+ aNewSection.maSep.dmOrientPage == 2)
+ std::swap(aNewSection.maSep.dxaLeft, aNewSection.maSep.dxaRight);
+
+ aNewSection.maSep.dzaGutter = ReadUSprm( pSep, pIds[5], 0);
+
+ aNewSection.maSep.fRTLGutter = static_cast< sal_uInt8 >(eVer >= ww::eWW8 ? ReadUSprm( pSep, 0x322A, 0 ) : 0);
+
+ // Page Number Restarts - sprmSFPgnRestart
+ aNewSection.maSep.fPgnRestart = ReadBSprm(pSep, pIds[6], 0);
+
+ aNewSection.maSep.pgnStart = ReadBSprm( pSep, pIds[7], 0 );
+
+ if (eVer >= ww::eWW6)
+ {
+ if (const BYTE* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 132 : 0x3001) ))
+ aNewSection.maSep.iHeadingPgn = *p;
+
+ if (const BYTE* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 131 : 0x3000) ))
+ aNewSection.maSep.cnsPgn = *p;
+ }
+
+ if(const BYTE* pSprmSDmBinFirst = pSep->HasSprm( pIds[8] ))
+ aNewSection.maSep.dmBinFirst = *pSprmSDmBinFirst;
+
+ if (const BYTE* pSprmSDmBinOther = pSep->HasSprm( pIds[9] ))
+ aNewSection.maSep.dmBinOther = *pSprmSDmBinOther;
+
+ static const USHORT nTop[] = { MM_250, 1440 };
+ static const USHORT nBot[] = { MM_200, 1440 };
+
+ static const USHORT aVer2Ids2[] =
+ {
+ /*sprmSDyaTop*/ 143,
+ /*sprmSDyaBottom*/ 144,
+ /*sprmSDyaHdrTop*/ 131,
+ /*sprmSDyaHdrBottom*/ 132,
+ /*sprmSNLnnMod*/ 129,
+ /*sprmSLnc*/ 127,
+ /*sprmSDxaLnn*/ 130,
+ /*sprmSLnnMin*/ 135
+ };
+
+ static const USHORT aVer67Ids2[] =
+ {
+ /*sprmSDyaTop*/ 168,
+ /*sprmSDyaBottom*/ 169,
+ /*sprmSDyaHdrTop*/ 156,
+ /*sprmSDyaHdrBottom*/ 157,
+ /*sprmSNLnnMod*/ 154,
+ /*sprmSLnc*/ 152,
+ /*sprmSDxaLnn*/ 155,
+ /*sprmSLnnMin*/ 160
+ };
+ static const USHORT aVer8Ids2[] =
+ {
+ /*sprmSDyaTop*/ 0x9023,
+ /*sprmSDyaBottom*/ 0x9024,
+ /*sprmSDyaHdrTop*/ 0xB017,
+ /*sprmSDyaHdrBottom*/ 0xB018,
+ /*sprmSNLnnMod*/ 0x5015,
+ /*sprmSLnc*/ 0x3013,
+ /*sprmSDxaLnn*/ 0x9016,
+ /*sprmSLnnMin*/ 0x501B
+ };
+
+ pIds = eVer <= ww::eWW2 ? aVer2Ids2 : eVer <= ww::eWW7 ? aVer67Ids2 : aVer8Ids2;
+
+ aNewSection.maSep.dyaTop = ReadSprm( pSep, pIds[0], nTop[nLIdx] );
+ aNewSection.maSep.dyaBottom = ReadSprm( pSep, pIds[1], nBot[nLIdx] );
+ aNewSection.maSep.dyaHdrTop = ReadUSprm( pSep, pIds[2], 720 );
+ aNewSection.maSep.dyaHdrBottom = ReadUSprm( pSep, pIds[3], 720 );
+
+ if (eVer >= ww::eWW8)
+ {
+ aNewSection.maSep.wTextFlow = ReadUSprm(pSep, 0x5033, 0);
+ aNewSection.maSep.clm = ReadUSprm( pSep, 0x5032, 0 );
+ aNewSection.maSep.dyaLinePitch = ReadUSprm(pSep, 0x9031, 360);
+ if (const BYTE* pS = pSep->HasSprm(0x7030))
+ aNewSection.maSep.dxtCharSpace = SVBT32ToUInt32(pS);
+
+ //sprmSPgbProp
+ sal_uInt16 pgbProp = ReadSprm( pSep, 0x522F, 0 );
+ aNewSection.maSep.pgbApplyTo = pgbProp & 0x0007;
+ aNewSection.maSep.pgbPageDepth = (pgbProp & 0x0018) >> 3;
+ aNewSection.maSep.pgbOffsetFrom = (pgbProp & 0x00E0) >> 5;
+
+ aNewSection.mnBorders =
+ ::lcl_ReadBorders(eVer <= ww::eWW7, aNewSection.brc, 0, 0, pSep);
+ }
+
+ // check if Line Numbering must be activated or resetted
+ if (const BYTE* pSprmSNLnnMod = pSep->HasSprm( pIds[4] ))
+ aNewSection.maSep.nLnnMod = *pSprmSNLnnMod;
+
+ if (const BYTE* pSprmSLnc = pSep->HasSprm( pIds[5] ))
+ aNewSection.maSep.lnc = *pSprmSLnc;
+
+ if (const BYTE* pSprmSDxaLnn = pSep->HasSprm( pIds[6] ))
+ aNewSection.maSep.dxaLnn = SVBT16ToShort( pSprmSDxaLnn );
+
+ if (const BYTE* pSprmSLnnMin = pSep->HasSprm( pIds[7] ))
+ aNewSection.maSep.lnnMin = *pSprmSLnnMin;
+
+ if (eVer <= ww::eWW7)
+ aNewSection.maSep.grpfIhdt = ReadBSprm(pSep, eVer <= ww::eWW2 ? 128 : 153, 0);
+ else if (mrReader.pHdFt)
+ {
+ aNewSection.maSep.grpfIhdt = WW8_HEADER_ODD | WW8_FOOTER_ODD;
+
+ if (aNewSection.HasTitlePage())
+ aNewSection.maSep.grpfIhdt |= WW8_HEADER_FIRST | WW8_FOOTER_FIRST;
+
+ if (mrReader.pWDop->fFacingPages)
+ aNewSection.maSep.grpfIhdt |= WW8_HEADER_EVEN | WW8_FOOTER_EVEN;
+
+ //See if we have a header or footer for each enabled possibility
+ //if we do not then we inherit the previous sections header/footer,
+ for (int nI = 0, nMask = 1; nI < 6; ++nI, nMask <<= 1)
+ {
+ if (aNewSection.maSep.grpfIhdt & nMask)
+ {
+ WW8_CP nStart;
+ long nLen;
+ mrReader.pHdFt->GetTextPosExact( static_cast< short >(nI + ( maSegments.size() + 1) * 6), nStart, nLen);
+ //No header or footer, inherit pervious one, or set to zero
+ //if no previous one
+ if (!nLen)
+ {
+ if (
+ maSegments.empty() ||
+ !(maSegments.back().maSep.grpfIhdt & nMask)
+ )
+ {
+ aNewSection.maSep.grpfIhdt &= ~nMask;
+ }
+ }
+ }
+ }
+ }
+
+ SetLeftRight(aNewSection);
+ //END read section values
+
+ if (eVer >= ww::eWW8)
+ aNewSection.SetDirection();
+
+ mrReader.HandleLineNumbering(aNewSection);
+ maSegments.push_back(aNewSection);
+}
+
+void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc* pOrgPageDesc,
+ SwPageDesc* pNewPageDesc, BYTE nCode )
+{
+ // copy first header content section
+ if (nCode & WW8_HEADER_FIRST)
+ rDoc.CopyHeader(pOrgPageDesc->GetMaster(), pNewPageDesc->GetMaster());
+
+ // copy first footer content section
+ if( nCode & WW8_FOOTER_FIRST )
+ rDoc.CopyFooter(pOrgPageDesc->GetMaster(), pNewPageDesc->GetMaster());
+
+ if( nCode & ( WW8_HEADER_ODD | WW8_FOOTER_ODD
+ | WW8_HEADER_EVEN | WW8_FOOTER_EVEN ) )
+ {
+ // copy odd header content section
+ if( nCode & WW8_HEADER_ODD )
+ {
+ rDoc.CopyHeader(pOrgPageDesc->GetMaster(),
+ pNewPageDesc->GetMaster() );
+ }
+ // copy odd footer content section
+ if( nCode & WW8_FOOTER_ODD )
+ {
+ rDoc.CopyFooter(pOrgPageDesc->GetMaster(),
+ pNewPageDesc->GetMaster());
+ }
+ // copy even header content section
+ if( nCode & WW8_HEADER_EVEN )
+ {
+ rDoc.CopyHeader(pOrgPageDesc->GetLeft(),
+ pNewPageDesc->GetLeft());
+ }
+ // copy even footer content section
+ if( nCode & WW8_FOOTER_EVEN )
+ {
+ rDoc.CopyFooter(pOrgPageDesc->GetLeft(),
+ pNewPageDesc->GetLeft());
+ }
+ }
+}
+
+//------------------------------------------------------
+// Hilfsroutinen fuer Grafiken und Apos und Tabellen
+//------------------------------------------------------
+
+static bool _SetWW8_BRC(bool bVer67, WW8_BRC& rVar, const BYTE* pS)
+{
+ if( pS )
+ {
+ if( bVer67 )
+ memcpy( rVar.aBits1, pS, sizeof( SVBT16 ) );
+ else
+ rVar = *((WW8_BRC*)pS);
+ }
+
+ return 0 != pS;
+}
+
+BYTE lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap,
+ const WW8RStyle* pSty, const WW8PLCFx_SEPX* pSep)
+{
+// Ausgegend von diesen defines:
+// #define WW8_TOP 0
+// #define WW8_LEFT 1
+// #define WW8_BOT 2
+// #define WW8_RIGHT 3
+// #define WW8_BETW 4
+
+//returns a BYTE filled with a bit for each position that had a sprm
+//setting that border
+
+ BYTE nBorder = false;
+ if( pSep )
+ {
+ if( !bVer67 )
+ {
+ BYTE* pSprm[4];
+
+ // sprmSBrcTop, sprmSBrcLeft, sprmSBrcBottom, sprmSBrcRight
+ if( pSep->Find4Sprms( 0x702B, 0x702C, 0x702D, 0x702E,
+ pSprm[0], pSprm[1], pSprm[2], pSprm[3] ) )
+ {
+ for( int i = 0; i < 4; ++i )
+ nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pSprm[ i ] ))<<i;
+ }
+ }
+ }
+ else
+ {
+
+ static const USHORT aVer67Ids[5] = { 38, 39, 40, 41, 42 };
+
+ static const USHORT aVer8Ids[5] =
+ { 0x6424, 0x6425, 0x6426, 0x6427, 0x6428 };
+
+ const USHORT* pIds = bVer67 ? aVer67Ids : aVer8Ids;
+
+ if( pPap )
+ {
+ for( int i = 0; i < 5; ++i, ++pIds )
+ nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pPap->HasSprm( *pIds )))<<i;
+ }
+ else if( pSty )
+ {
+ for( int i = 0; i < 5; ++i, ++pIds )
+ nBorder |= (_SetWW8_BRC( bVer67, brc[ i ], pSty->HasParaSprm( *pIds )))<<i;
+ }
+ else {
+ ASSERT( pSty || pPap, "WW8PLCFx_Cp_FKP and WW8RStyle "
+ "and WW8PLCFx_SEPX is 0" );
+ }
+ }
+
+ return nBorder;
+}
+
+void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, BYTE nCol, short nIdx,
+ USHORT nOOIndex, USHORT nWWIndex, short *pSize=0)
+{
+ WW8_BordersSO::eBorderCode eCodeIdx;
+
+ //Word mirrors some indexes inside outside depending on its position, we
+ //don't do that, so flip them here
+ if (nWWIndex == WW8_TOP || nWWIndex == WW8_LEFT)
+ {
+ switch (nIdx)
+ {
+ case 11:
+ case 12:
+ nIdx = (nIdx == 11) ? 12 : 11;
+ break;
+ case 14:
+ case 15:
+ nIdx = (nIdx == 14) ? 15 : 14;
+ break;
+ case 17:
+ case 18:
+ nIdx = (nIdx == 17) ? 18 : 17;
+ break;
+ case 24:
+ case 25:
+ nIdx = (nIdx == 24) ? 25 : 24;
+ break;
+ }
+ }
+
+ // Map to our border types, we should use of one equal line
+ // thickness, or one of smaller thickness. If too small we
+ // can make the defecit up in additional white space or
+ // object size
+ switch (nIdx)
+ {
+ // First the single lines
+ case 1:
+ case 2:
+ case 5:
+ // and the unsupported special cases which we map to a single line
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ case 22:
+ // or if in necessary by a double line
+ case 24:
+ case 25:
+ if( nLineThickness < 10)
+ eCodeIdx = WW8_BordersSO::single0;// 1 Twip for us
+ else if( nLineThickness < 20)
+ eCodeIdx = WW8_BordersSO::single5;// 10 Twips for us
+ else if (nLineThickness < 50)
+ eCodeIdx = WW8_BordersSO::single1;// 20 Twips
+ else if (nLineThickness < 80)
+ eCodeIdx = WW8_BordersSO::single2;// 50
+ else if (nLineThickness < 100)
+ eCodeIdx = WW8_BordersSO::single3;// 80
+ else if (nLineThickness < 150)
+ eCodeIdx = WW8_BordersSO::single4;// 100
+ // Hack: for the quite thick lines we must paint double lines,
+ // because our singles lines don't come thicker than 5 points.
+ else if (nLineThickness < 180)
+ eCodeIdx = WW8_BordersSO::double2;// 150
+ else
+ eCodeIdx = WW8_BordersSO::double5;// 180
+ break;
+ // then the shading beams which we represent by a double line
+ case 23:
+ eCodeIdx = WW8_BordersSO::double1;
+ break;
+ // then the double lines, for which we have good matches
+ case 3:
+ case 10: //Don't have tripple so use double
+ if (nLineThickness < 60)
+ eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
+ else if (nLineThickness < 135)
+ eCodeIdx = WW8_BordersSO::double7;// some more space
+ else if (nLineThickness < 180)
+ eCodeIdx = WW8_BordersSO::double1;// 60
+ else
+ eCodeIdx = WW8_BordersSO::double2;// 150
+ break;
+ case 11:
+ eCodeIdx = WW8_BordersSO::double4;// 90 Twips for us
+ break;
+ case 12:
+ case 13: //Don't have thin thick thin, so use thick thin
+ if (nLineThickness < 87)
+ eCodeIdx = WW8_BordersSO::double8;// 71 Twips for us
+ else if (nLineThickness < 117)
+ eCodeIdx = WW8_BordersSO::double9;// 101
+ else if (nLineThickness < 166)
+ eCodeIdx = WW8_BordersSO::double10;// 131
+ else
+ eCodeIdx = WW8_BordersSO::double5;// 180
+ break;
+ case 14:
+ if (nLineThickness < 46)
+ eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
+ else if (nLineThickness < 76)
+ eCodeIdx = WW8_BordersSO::double1;// 60
+ else if (nLineThickness < 121)
+ eCodeIdx = WW8_BordersSO::double4;// 90
+ else if (nLineThickness < 166)
+ eCodeIdx = WW8_BordersSO::double2;// 150
+ else
+ eCodeIdx = WW8_BordersSO::double6;// 180
+ break;
+ case 15:
+ case 16: //Don't have thin thick thin, so use thick thin
+ if (nLineThickness < 46)
+ eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
+ else if (nLineThickness < 76)
+ eCodeIdx = WW8_BordersSO::double1;// 60
+ else if (nLineThickness < 121)
+ eCodeIdx = WW8_BordersSO::double3;// 90
+ else if (nLineThickness < 166)
+ eCodeIdx = WW8_BordersSO::double2;// 150
+ else
+ eCodeIdx = WW8_BordersSO::double5;// 180
+ break;
+ case 17:
+ if (nLineThickness < 46)
+ eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
+ else if (nLineThickness < 72)
+ eCodeIdx = WW8_BordersSO::double7;// 52
+ else if (nLineThickness < 137)
+ eCodeIdx = WW8_BordersSO::double4;// 90
+ else
+ eCodeIdx = WW8_BordersSO::double6;// 180
+ break;
+ case 18:
+ case 19: //Don't have thin thick thin, so use thick thin
+ if (nLineThickness < 46)
+ eCodeIdx = WW8_BordersSO::double0;// 22 Twips for us
+ else if (nLineThickness < 62)
+ eCodeIdx = WW8_BordersSO::double7;// 52
+ else if (nLineThickness < 87)
+ eCodeIdx = WW8_BordersSO::double8;// 71
+ else if (nLineThickness < 117)
+ eCodeIdx = WW8_BordersSO::double9;// 101
+ else if (nLineThickness < 156)
+ eCodeIdx = WW8_BordersSO::double10;// 131
+ else
+ eCodeIdx = WW8_BordersSO::double5;// 180
+ break;
+ case 20:
+ if (nLineThickness < 46)
+ eCodeIdx = WW8_BordersSO::single1; // 20 Twips for us
+ else
+ eCodeIdx = WW8_BordersSO::double1;// 60
+ break;
+ case 21:
+ eCodeIdx = WW8_BordersSO::double1;// 60 Twips for us
+ break;
+ default:
+ eCodeIdx = WW8_BordersSO::single0;
+ break;
+ }
+
+ const WW8_BordersSO& rBorders = WW8_BordersSO::Get0x01LineMatch(eCodeIdx);
+ SvxBorderLine aLine;
+ aLine.SetOutWidth(rBorders.mnOut);
+ aLine.SetInWidth(rBorders.mnIn);
+ aLine.SetDistance(rBorders.mnDist);
+
+ //No AUTO for borders as yet, so if AUTO, use BLACK
+ if (nCol == 0)
+ nCol = 1;
+
+ aLine.SetColor(SwWW8ImplReader::GetCol(nCol));
+
+ if (pSize)
+ pSize[nWWIndex] = nLineThickness+nSpace;
+
+ rBox.SetLine(&aLine, nOOIndex);
+ rBox.SetDistance(nSpace, nOOIndex);
+
+}
+
+void Set1Border(bool bVer67, SvxBoxItem &rBox, const WW8_BRC& rBor,
+ USHORT nOOIndex, USHORT nWWIndex, short *pSize=0)
+{
+ BYTE nCol;
+ short nSpace, nIdx;
+ short nLineThickness = rBor.DetermineBorderProperties(bVer67,&nSpace,&nCol,
+ &nIdx);
+
+ GetLineIndex(rBox, nLineThickness, nSpace, nCol, nIdx, nOOIndex, nWWIndex, pSize );
+
+}
+
+bool lcl_IsBorder(bool bVer67, const WW8_BRC* pbrc, bool bChkBtwn = false)
+{
+ if( bVer67 )
+ return ( pbrc[WW8_TOP ].aBits1[0] & 0x18 ) || // brcType != 0
+ ( pbrc[WW8_LEFT ].aBits1[0] & 0x18 ) ||
+ ( pbrc[WW8_BOT ].aBits1[0] & 0x18 ) ||
+ ( pbrc[WW8_RIGHT].aBits1[0] & 0x18 ) ||
+ ( bChkBtwn && ( pbrc[WW8_BETW ].aBits1[0] )) ||
+ //can have dotted and dashed with a brcType of 0
+ ( (pbrc[WW8_TOP ].aBits1[0] & 0x07)+1 > 6) ||
+ ( (pbrc[WW8_LEFT ].aBits1[0] & 0x07)+1 > 6) ||
+ ( (pbrc[WW8_BOT ].aBits1[0] & 0x07)+1 > 6) ||
+ ( (pbrc[WW8_RIGHT].aBits1[0] & 0x07)+1 > 6) ||
+ ( bChkBtwn && ( (pbrc[WW8_BETW ].aBits1[0] & 0x07)+1 > 6))
+ ;
+ // Abfrage auf 0x1f statt 0x18 ist noetig, da zumindest einige
+ // WW-Versionen ( 6.0 US ) bei dotted brcType auf 0 setzen
+ else
+ return pbrc[WW8_TOP ].aBits1[1] || // brcType != 0
+ pbrc[WW8_LEFT ].aBits1[1] ||
+ pbrc[WW8_BOT ].aBits1[1] ||
+ pbrc[WW8_RIGHT].aBits1[1] ||
+ (bChkBtwn && pbrc[WW8_BETW ].aBits1[1]);
+}
+
+bool SwWW8ImplReader::IsBorder(const WW8_BRC* pbrc, bool bChkBtwn) const
+{
+ return lcl_IsBorder(bVer67, pbrc, bChkBtwn);
+}
+
+bool WW8_BRC::IsEmpty(bool bVer67) const
+{
+ return (IsBlank() || IsZeroed(bVer67));
+}
+
+bool WW8_BRC::IsBlank() const
+{
+ return (aBits1[0] == 0xff && aBits1[1] == 0xff);
+}
+
+bool WW8_BRC::IsZeroed(bool bVer67) const
+{
+ return (!(bVer67 ? (aBits1[0] & 0x001f) : aBits1[1]));
+}
+
+bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc,
+ short *pSizeArray, BYTE nSetBorders) const
+{
+ bool bChange = false;
+ static const USHORT aIdArr[ 10 ] =
+ {
+ WW8_TOP, BOX_LINE_TOP,
+ WW8_LEFT, BOX_LINE_LEFT,
+ WW8_RIGHT, BOX_LINE_RIGHT,
+ WW8_BOT, BOX_LINE_BOTTOM,
+ WW8_BETW, BOX_LINE_BOTTOM
+ };
+
+ for( int i = 0, nEnd = 8; i < nEnd; i += 2 )
+ {
+ // ungueltige Borders ausfiltern
+ const WW8_BRC& rB = pbrc[ aIdArr[ i ] ];
+ if( !rB.IsEmpty(bVer67))
+ {
+ Set1Border(bVer67, rBox, rB, aIdArr[i+1], aIdArr[i], pSizeArray);
+ bChange = true;
+ }
+ else if ( nSetBorders & (1 << aIdArr[i]) )
+ {
+ /*
+ ##826##, ##653##
+
+ If a style has borders set,and the para attributes attempt remove
+ the borders, then this is perfectably acceptable, so we shouldn't
+ ignore this blank entry
+
+ nSetBorders has a bit set for each location that a sprm set a
+ border, so with a sprm set, but no border, then disable the
+ appropiate border
+ */
+ rBox.SetLine( 0, aIdArr[ i+1 ] );
+ }
+ }
+ return bChange;
+}
+
+
+bool SwWW8ImplReader::SetShadow(SvxShadowItem& rShadow, const short *pSizeArray,
+ const WW8_BRC *pbrc) const
+{
+ bool bRet = (
+ ( bVer67 ? (pbrc[WW8_RIGHT].aBits1[ 1 ] & 0x20 )
+ : (pbrc[WW8_RIGHT].aBits2[ 1 ] & 0x20 ) )
+ && (pSizeArray && pSizeArray[WW8_RIGHT])
+ );
+ if (bRet)
+ {
+ rShadow.SetColor(Color(COL_BLACK));
+ short nVal = pSizeArray[WW8_RIGHT];
+ if (nVal < 0x10)
+ nVal = 0x10;
+ rShadow.SetWidth(nVal);
+ rShadow.SetLocation(SVX_SHADOW_BOTTOMRIGHT);
+ bRet = true;
+ }
+ return bRet;
+}
+
+void SwWW8ImplReader::GetBorderDistance(const WW8_BRC* pbrc,
+ Rectangle& rInnerDist) const
+{
+ // 'dptSpace' is stored in 3 bits of 'Border Code (BRC)'
+ if (bVer67)
+ {
+ rInnerDist = Rectangle(((pbrc[ 1 ].aBits1[1] >> 3) & 0x1f) * 20,
+ ((pbrc[ 0 ].aBits1[1] >> 3) & 0x1f) * 20,
+ ((pbrc[ 3 ].aBits1[1] >> 3) & 0x1f) * 20,
+ ((pbrc[ 2 ].aBits1[1] >> 3) & 0x1f) * 20 );
+ }
+ else
+ {
+ rInnerDist = Rectangle( (pbrc[ 1 ].aBits2[1] & 0x1f) * 20,
+ (pbrc[ 0 ].aBits2[1] & 0x1f) * 20,
+ (pbrc[ 3 ].aBits2[1] & 0x1f) * 20,
+ (pbrc[ 2 ].aBits2[1] & 0x1f) * 20 );
+ }
+}
+
+
+bool SwWW8ImplReader::SetFlyBordersShadow(SfxItemSet& rFlySet,
+ const WW8_BRC *pbrc, short *pSizeArray) const
+{
+ bool bShadowed = false;
+ if (IsBorder(pbrc))
+ {
+ SvxBoxItem aBox( RES_BOX );
+ SetBorder(aBox, pbrc, pSizeArray);
+
+ rFlySet.Put( aBox );
+
+ // fShadow
+ SvxShadowItem aShadow( RES_SHADOW );
+ if( SetShadow( aShadow, pSizeArray, pbrc ))
+ {
+ bShadowed = true;
+ rFlySet.Put( aShadow );
+ }
+ }
+ return bShadowed;
+}
+
+//-----------------------------------------
+// APOs
+//-----------------------------------------
+ // fuer Berechnung der minimalen FrameSize
+#define MAX_BORDER_SIZE 210 // so breit ist max. der Border
+#define MAX_EMPTY_BORDER 10 // fuer +-1-Fehler, mindestens 1
+
+static void FlySecur1(short& rSize, const bool bBorder)
+{
+ short nMin = MINFLY +
+ bBorder ? MAX_BORDER_SIZE : MAX_EMPTY_BORDER;
+
+ if ( rSize < nMin )
+ rSize = nMin;
+}
+
+inline bool SetValSprm( INT16* pVar, WW8PLCFx_Cp_FKP* pPap, USHORT nId )
+{
+ const BYTE* pS = pPap->HasSprm( nId );
+ if( pS )
+ *pVar = (INT16)SVBT16ToShort( pS );
+ return ( pS != 0 );
+}
+
+inline bool SetValSprm( INT16* pVar, const WW8RStyle* pStyle, USHORT nId )
+{
+ const BYTE* pS = pStyle->HasParaSprm( nId );
+ if( pS )
+ *pVar = (INT16)SVBT16ToShort( pS );
+ return ( pS != 0 );
+}
+
+/*
+#i1930 revealed that sprm 0x360D as used in tables can affect the frame
+around the table. Its full structure is not fully understood as yet.
+*/
+void WW8FlyPara::ApplyTabPos(const WW8_TablePos *pTabPos)
+{
+ if (pTabPos)
+ {
+ nSp26 = pTabPos->nSp26;
+ nSp27 = pTabPos->nSp27;
+ nSp29 = pTabPos->nSp29;
+ nLeMgn = pTabPos->nLeMgn;
+ nRiMgn = pTabPos->nRiMgn;
+ nUpMgn = pTabPos->nUpMgn;
+ nLoMgn = pTabPos->nLoMgn;
+ nSp37 = pTabPos->nSp37;
+ }
+}
+
+WW8FlyPara::WW8FlyPara(bool bIsVer67, const WW8FlyPara* pSrc /* = 0 */)
+{
+ if ( pSrc )
+ memcpy( this, pSrc, sizeof( WW8FlyPara ) ); // Copy-Ctor
+ else
+ {
+ memset( this, 0, sizeof( WW8FlyPara ) ); // Default-Ctor
+ nSp37 = 2; // Default: Umfluss
+ }
+ bVer67 = bIsVer67;
+}
+
+bool WW8FlyPara::operator==(const WW8FlyPara& rSrc) const
+{
+ /*
+ Compare the parts that word seems to compare for equivalence.
+ Interestingly being autoheight or absolute height (the & 0x7fff) doesn't
+ matter to word e.g. #110507#
+ */
+ return
+ (
+ (nSp26 == rSrc.nSp26) &&
+ (nSp27 == rSrc.nSp27) &&
+ ((nSp45 & 0x7fff) == (rSrc.nSp45 & 0x7fff)) &&
+ (nSp28 == rSrc.nSp28) &&
+ (nLeMgn == rSrc.nLeMgn) &&
+ (nRiMgn == rSrc.nRiMgn) &&
+ (nUpMgn == rSrc.nUpMgn) &&
+ (nLoMgn == rSrc.nLoMgn) &&
+ (nSp29 == rSrc.nSp29) &&
+ (nSp37 == rSrc.nSp37)
+ );
+}
+
+// Read fuer normalen Text
+void WW8FlyPara::Read(const BYTE* pSprm29, WW8PLCFx_Cp_FKP* pPap)
+{
+ if (pSprm29)
+ nOrigSp29 = *pSprm29; // PPC ( Bindung )
+
+ const BYTE* pS = 0;
+ if( bVer67 )
+ {
+ SetValSprm( &nSp26, pPap, 26 ); // X-Position //sprmPDxaAbs
+ //set in me or in parent style
+ mbVertSet |= SetValSprm( &nSp27, pPap, 27 ); // Y-Position //sprmPDyaAbs
+ SetValSprm( &nSp45, pPap, 45 ); // Hoehe //sprmPWHeightAbs
+ SetValSprm( &nSp28, pPap, 28 ); // Breite //sprmPDxaWidth
+ SetValSprm( &nLeMgn, pPap, 49 ); // L-Raender //sprmPDxaFromText
+ SetValSprm( &nRiMgn, pPap, 49 ); // R-Raender //sprmPDxaFromText
+ SetValSprm( &nUpMgn, pPap, 48 ); // U-Raender //sprmPDyaFromText
+ SetValSprm( &nLoMgn, pPap, 48 ); // D-Raender //sprmPDyaFromText
+
+ pS = pPap->HasSprm( 37 ); //sprmPWr
+ if( pS )
+ nSp37 = *pS;
+ }
+ else
+ {
+ SetValSprm( &nSp26, pPap, 0x8418 ); // X-Position
+ //set in me or in parent style
+ mbVertSet |= SetValSprm( &nSp27, pPap, 0x8419 ); // Y-Position
+ SetValSprm( &nSp45, pPap, 0x442B ); // Hoehe
+ SetValSprm( &nSp28, pPap, 0x841A ); // Breite
+ SetValSprm( &nLeMgn, pPap, 0x842F ); // L-Raender
+ SetValSprm( &nRiMgn, pPap, 0x842F ); // R-Raender
+ SetValSprm( &nUpMgn, pPap, 0x842E ); // U-Raender
+ SetValSprm( &nLoMgn, pPap, 0x842E ); // D-Raender
+
+ pS = pPap->HasSprm( 0x2423 ); // Umfluss
+ if( pS )
+ nSp37 = *pS;
+ }
+
+ if( ::lcl_ReadBorders( bVer67, brc, pPap )) // Umrandung
+ bBorderLines = ::lcl_IsBorder( bVer67, brc );
+
+ /*
+ #i8798#
+ Appears that with no dyaAbs set then the actual vert anchoring set is
+ ignored and we remain relative to text, so if that is the case we are 0
+ from para anchor, so we update the frame to have explicitly this type of
+ anchoring
+ */
+ if (!mbVertSet)
+ nSp29 = (nOrigSp29 & 0xCF) | 0x20;
+ else
+ nSp29 = nOrigSp29;
+}
+
+void WW8FlyPara::ReadFull(const BYTE* pSprm29, SwWW8ImplReader* pIo)
+{
+ WW8PLCFMan* pPlcxMan = pIo->pPlcxMan;
+ WW8PLCFx_Cp_FKP* pPap = pPlcxMan->GetPapPLCF();
+
+ Read(pSprm29, pPap); // Lies Apo-Parameter
+
+ do{ // Block zum rausspringen
+ if( nSp45 != 0 /* || nSp28 != 0 */ )
+ break; // bGrafApo nur bei Hoehe automatisch
+ if( pIo->pWwFib->fComplex )
+ break; // (*pPap)++ geht bei FastSave schief
+ // -> bei FastSave kein Test auf Grafik-APO
+ SvStream* pIoStrm = pIo->pStrm;
+ ULONG nPos = pIoStrm->Tell();
+ WW8PLCFxSave1 aSave;
+ pPlcxMan->GetPap()->Save( aSave );
+ bGrafApo = false;
+
+ do{ // Block zum rausspringen
+
+ BYTE nTxt[2];
+
+ pIoStrm->Read( nTxt, 2 ); // lies Text
+ if( nTxt[0] != 0x01 || nTxt[1] != 0x0d )// nur Grafik + CR ?
+ break; // Nein
+
+ (*pPap)++; // Naechste Zeile
+
+ // In APO ?
+ //sprmPPc
+ const BYTE* pS = pPap->HasSprm( bVer67 ? 29 : 0x261B );
+
+ // Nein -> Grafik-Apo
+ if( !pS ){
+ bGrafApo = true;
+ break; // Ende des APO
+ }
+
+ ww::WordVersion eVer = pIo->GetFib().GetFIBVersion();
+ WW8FlyPara *pNowStyleApo=0;
+ USHORT nColl = pPap->GetIstd();
+ ww::sti eSti = eVer < ww::eWW6 ? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8 >(nColl) ) : static_cast<ww::sti>(nColl);
+ while (eSti != ww::stiNil && 0 == (pNowStyleApo = pIo->pCollA[nColl].pWWFly))
+ {
+ nColl = pIo->pCollA[nColl].nBase;
+ eSti = eVer < ww::eWW6 ? ww::GetCanonicalStiFromStc( static_cast< sal_uInt8 >(nColl) ) : static_cast<ww::sti>(nColl);
+ }
+
+ WW8FlyPara aF(bVer67, pNowStyleApo);
+ // Neuer FlaPara zum Vergleich
+ aF.Read( pS, pPap ); // WWPara fuer neuen Para
+ if( !( aF == *this ) ) // selber APO ? ( oder neuer ? )
+ bGrafApo = true; // nein -> 1-zeiliger APO
+ // -> Grafik-APO
+ }
+ while( 0 ); // Block zum rausspringen
+
+ pPlcxMan->GetPap()->Restore( aSave );
+ pIoStrm->Seek( nPos );
+ }while( 0 ); // Block zum rausspringen
+}
+
+
+// Read fuer Apo-Defs in Styledefs
+void WW8FlyPara::Read(const BYTE* pSprm29, WW8RStyle* pStyle)
+{
+ if (pSprm29)
+ nOrigSp29 = *pSprm29; // PPC ( Bindung )
+
+ const BYTE* pS = 0;
+ if (bVer67)
+ {
+ SetValSprm( &nSp26, pStyle, 26 ); // X-Position
+ //set in me or in parent style
+ mbVertSet |= SetValSprm(&nSp27, pStyle, 27); // Y-Position
+ SetValSprm( &nSp45, pStyle, 45 ); // Hoehe
+ SetValSprm( &nSp28, pStyle, 28 ); // Breite
+ SetValSprm( &nLeMgn, pStyle, 49 ); // L-Raender
+ SetValSprm( &nRiMgn, pStyle, 49 ); // R-Raender
+ SetValSprm( &nUpMgn, pStyle, 48 ); // U-Raender
+ SetValSprm( &nLoMgn, pStyle, 48 ); // D-Raender
+
+ pS = pStyle->HasParaSprm( 37 ); // Umfluss
+ if( pS )
+ nSp37 = *pS;
+ }
+ else
+ {
+ SetValSprm( &nSp26, pStyle, 0x8418 ); // X-Position
+ //set in me or in parent style
+ mbVertSet |= SetValSprm(&nSp27, pStyle, 0x8419); // Y-Position
+ SetValSprm( &nSp45, pStyle, 0x442B ); // Hoehe
+ SetValSprm( &nSp28, pStyle, 0x841A ); // Breite
+ SetValSprm( &nLeMgn, pStyle, 0x842F ); // L-Raender
+ SetValSprm( &nRiMgn, pStyle, 0x842F ); // R-Raender
+ SetValSprm( &nUpMgn, pStyle, 0x842E ); // U-Raender
+ SetValSprm( &nLoMgn, pStyle, 0x842E ); // D-Raender
+
+ pS = pStyle->HasParaSprm( 0x2423 ); // Umfluss
+ if( pS )
+ nSp37 = *pS;
+ }
+
+ if (::lcl_ReadBorders(bVer67, brc, 0, pStyle)) // Umrandung
+ bBorderLines = ::lcl_IsBorder(bVer67, brc);
+
+ /*
+ #i8798#
+ Appears that with no dyaAbs set then the actual vert anchoring set is
+ ignored and we remain relative to text, so if that is the case we are 0
+ from para anchor, so we update the frame to have explicitly this type of
+ anchoring
+ */
+ if (!mbVertSet)
+ nSp29 = (nOrigSp29 & 0xCF) | 0x20;
+ else
+ nSp29 = nOrigSp29;
+}
+
+bool WW8FlyPara::IsEmpty() const
+{
+ WW8FlyPara aEmpty(bVer67);
+ /*
+ wr of 0 like 2 appears to me to be equivalent for checking here. See
+ #107103# if wrong, so given that the empty is 2, if we are 0 then set
+ empty to 0 to make 0 equiv to 2 for empty checking
+ */
+ ASSERT(aEmpty.nSp37 == 2, "this is not what we expect for nSp37");
+ if (this->nSp37 == 0)
+ aEmpty.nSp37 = 0;
+ if (aEmpty == *this)
+ return true;
+ return false;
+}
+
+// OD 14.10.2003 #i18732# - changes made on behalf of CMC
+WW8SwFlyPara::WW8SwFlyPara( SwPaM& rPaM,
+ SwWW8ImplReader& rIo,
+ WW8FlyPara& rWW,
+ const sal_uInt32 nWWPgTop,
+ const sal_uInt32 nPgLeft,
+ const sal_uInt32 nPgWidth,
+ const INT32 nIniFlyDx,
+ const INT32 nIniFlyDy )
+{
+ (void) rPaM;
+ (void) nPgLeft;
+
+ memset( this, 0, sizeof( WW8SwFlyPara ) ); // Initialisieren
+ nNewNettoWidth = MINFLY; // Minimum
+
+ eSurround = ( rWW.nSp37 > 1 ) ? SURROUND_IDEAL : SURROUND_NONE;
+
+ /*
+ #95905#, #83307# seems to have gone away now, so reenable parallel
+ wrapping support for frames in headers/footers. I don't know if we truly
+ have an explictly specified behaviour for these circumstances.
+ */
+
+ nHeight = rWW.nSp45;
+ if( nHeight & 0x8000 )
+ {
+ nHeight &= 0x7fff;
+ eHeightFix = ATT_MIN_SIZE;
+ }
+ else
+ eHeightFix = ATT_FIX_SIZE;
+
+ if( nHeight <= MINFLY )
+ { // keine Angabe oder Stuss
+ eHeightFix = ATT_MIN_SIZE;
+ nHeight = MINFLY;
+ }
+
+ nWidth = nNettoWidth = rWW.nSp28;
+ if( nWidth <= 10 ) // Auto-Breite
+ {
+ bAutoWidth = true;
+ rIo.maTracer.Log(sw::log::eAutoWidthFrame);
+ nWidth = nNettoWidth =
+ msword_cast<sal_Int16>((nPgWidth ? nPgWidth : 2268)); // 4 cm
+ }
+ if( nWidth <= MINFLY )
+ nWidth = nNettoWidth = MINFLY; // Minimale Breite
+
+ eVAlign = text::VertOrientation::NONE; // Defaults
+ eHAlign = text::HoriOrientation::NONE;
+ nYPos = 0;
+ nXPos = 0;
+
+ nRiMgn = rWW.nRiMgn;
+ nLeMgn = rWW.nLeMgn;
+ nLoMgn = rWW.nLoMgn;
+ nUpMgn = rWW.nUpMgn;
+
+ /*
+ See issue #i9178# for the 9 anchoring options, and make sure they stay
+ working if you modify the anchoring logic here.
+ */
+
+ // Wenn der Fly links, rechts, oben oder unten aligned ist,
+ // wird der aeussere Textabstand ignoriert, da sonst
+ // der Fly an falscher Position landen wuerde
+ // JP 18.11.98: Problematisch wird es nur bei Innen/Aussen
+
+ // Bindung
+ nYBind = (( rWW.nSp29 & 0x30 ) >> 4);
+ // --> OD 2005-08-24 #i53725# - absolute positioned objects have to be
+ // anchored at-paragraph to assure its correct anchor position.
+ eAnchor = FLY_AT_PARA;
+ // <--
+ switch (nYBind)
+ {
+ case 0: //relative to margin
+ eVRel = text::RelOrientation::PAGE_PRINT_AREA;
+ break;
+ case 1: //relative to page
+ eVRel = text::RelOrientation::PAGE_FRAME;
+ break;
+ default: //relative to text
+ eVRel = text::RelOrientation::FRAME;
+ break;
+ }
+
+// OD 14.10.2003 #i18732#
+ switch( rWW.nSp27 ) // besondere Y-Positionen ?
+ {
+ case -4:
+ eVAlign = text::VertOrientation::TOP;
+ if (nYBind < 2)
+ nUpMgn = 0;
+ break; // oben
+ case -8:
+ eVAlign = text::VertOrientation::CENTER;
+ break; // zentriert
+ case -12:
+ eVAlign = text::VertOrientation::BOTTOM;
+ if (nYBind < 2)
+ nLoMgn = 0;
+ break; // unten
+ default:
+ nYPos = rWW.nSp27 + (short)nIniFlyDy;
+ break; // Korrekturen per Ini-Datei
+ }
+
+ switch( rWW.nSp26 ) // besondere X-Positionen ?
+ {
+ case 0:
+ eHAlign = text::HoriOrientation::LEFT;
+ nLeMgn = 0;
+ break; // links
+ case -4:
+ eHAlign = text::HoriOrientation::CENTER;
+ break; // zentriert
+ case -8:
+ eHAlign = text::HoriOrientation::RIGHT;
+ nRiMgn = 0;
+ break; // rechts
+ case -12:
+ eHAlign = text::HoriOrientation::LEFT;
+ bToggelPos = true;
+ break; // innen
+ case -16:
+ eHAlign = text::HoriOrientation::RIGHT;
+ bToggelPos = true;
+ break; // aussen
+ default:
+ nXPos = rWW.nSp26 + (short)nIniFlyDx;
+ break; // Korrekturen per Ini-Datei
+ }
+
+ nXBind = ( rWW.nSp29 & 0xc0 ) >> 6;
+// OD 14.10.2003 #i18732#
+ switch (nXBind) // X - Bindung -> Koordinatentransformation
+ {
+ case 0: //relative to column
+ eHRel = text::RelOrientation::FRAME;
+ break;
+ case 1: //relative to margin
+ eHRel = text::RelOrientation::PAGE_PRINT_AREA;
+ break;
+ default: //relative to page
+ eHRel = text::RelOrientation::PAGE_FRAME;
+ break;
+ }
+
+ // --> OD 2004-12-06 #i36649# - adjustments for certain horizontal alignments
+ // Note: These special adjustments found by an investigation of documents
+ // containing frames with different left/right border distances and
+ // distances to text. The outcome is some how strange.
+ // Note: These adjustments causes wrong horizontal positions for frames,
+ // which are aligned inside|outside to page|margin on even pages,
+ // the left and right border distances are different.
+ // --> OD 2005-01-19 #119176# - no adjustments possible, if frame has
+ // automatic width.
+ // determine left border distance
+ INT16 nLeBorderMgn( 0L );
+ if ( !bAutoWidth )
+ {
+ INT16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
+ &nLeBorderMgn);
+ nLeBorderMgn = nLeBorderMgn + nTemp;
+ }
+ // determine right border distance
+ INT16 nRiBorderMgn( 0L );
+ if ( !bAutoWidth )
+ {
+ INT16 nTemp = rWW.brc[WW8_RIGHT].DetermineBorderProperties(rWW.bVer67,
+ &nRiBorderMgn);
+ nRiBorderMgn = nRiBorderMgn + nTemp;
+ }
+ if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_FRAME )
+ {
+ // convert 'left to page' to
+ // 'from left -<width>-<2*left border distance>-<right wrap distance>
+ // to page text area'
+ eHAlign = text::HoriOrientation::NONE;
+ eHRel = text::RelOrientation::PAGE_PRINT_AREA;
+ nXPos = -nWidth - (2*nLeBorderMgn) - rWW.nRiMgn;
+ // re-set left wrap distance
+ nLeMgn = rWW.nLeMgn;
+ }
+ else if ( !bAutoWidth && eHAlign == text::HoriOrientation::RIGHT && eHRel == text::RelOrientation::PAGE_FRAME )
+ {
+ // convert 'right to page' to
+ // 'from left <right border distance-left border distance>+<left wrap distance>
+ // to right page border'
+ eHAlign = text::HoriOrientation::NONE;
+ eHRel = text::RelOrientation::PAGE_RIGHT;
+ nXPos = ( nRiBorderMgn - nLeBorderMgn ) + rWW.nLeMgn;
+ // re-set right wrap distance
+ nRiMgn = rWW.nRiMgn;
+ }
+ else if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_PRINT_AREA )
+ {
+ // convert 'left to margin' to
+ // 'from left -<left border distance> to page text area'
+ eHAlign = text::HoriOrientation::NONE;
+ eHRel = text::RelOrientation::PAGE_PRINT_AREA;
+ nXPos = -nLeBorderMgn;
+ // re-set left wrap distance
+ nLeMgn = rWW.nLeMgn;
+ }
+ else if ( !bAutoWidth && eHAlign == text::HoriOrientation::RIGHT && eHRel == text::RelOrientation::PAGE_PRINT_AREA )
+ {
+ // convert 'right to margin' to
+ // 'from left -<width>-<left border distance> to right page border'
+ eHAlign = text::HoriOrientation::NONE;
+ eHRel = text::RelOrientation::PAGE_RIGHT;
+ nXPos = -nWidth - nLeBorderMgn;
+ // re-set right wrap distance
+ nRiMgn = rWW.nRiMgn;
+ }
+ else if (rWW.bBorderLines)
+ // <--
+ {
+ /*
+ #i582#
+ Word has a curious bug where the offset stored do not take into
+ account the internal distance from the corner both
+ */
+ INT16 nLeLMgn = 0;
+ INT16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
+ &nLeLMgn);
+ nLeLMgn = nLeLMgn + nTemp;
+
+ if (nLeLMgn)
+ {
+ if (eHAlign == text::HoriOrientation::LEFT)
+ eHAlign = text::HoriOrientation::NONE;
+ nXPos = nXPos - nLeLMgn;
+ }
+ }
+
+ // --> OD 2007-07-03 #148498#
+ // adjustments for certain vertical alignments
+ if ( eVAlign == text::VertOrientation::NONE && eVRel == text::RelOrientation::PAGE_PRINT_AREA )
+ {
+ // convert "<X> from top page text area" to
+ // "<X + page top margin> from page"
+ eVRel = text::RelOrientation::PAGE_FRAME;
+ nYPos = static_cast< INT16 >( nYPos + nWWPgTop );
+ }
+ // <--
+
+ FlySecur1( nWidth, rWW.bBorderLines ); // passen Raender ?
+ FlySecur1( nHeight, rWW.bBorderLines );
+
+}
+
+// hat ein Fly in WW eine automatische Breite, dann muss das durch
+// nachtraegliches Anpassen der ( im SW festen ) Fly-Breite simuliert werden.
+// Dabei kann die Fly-Breite groesser oder kleiner werden, da der Default-Wert
+// ohne Wissen ueber den Inhalt eingesetzt wird.
+void WW8SwFlyPara::BoxUpWidth( long nInWidth )
+{
+ if( bAutoWidth && nInWidth > nNewNettoWidth )
+ nNewNettoWidth = nInWidth;
+};
+
+// Die Klasse WW8FlySet ist von SfxItemSet abgeleitet und stellt auch
+// im Prizip nicht mehr zur Verfuegung, ist aber fuer mich besser
+// zu handeln
+// WW8FlySet-ctor fuer Apos und Graf-Apos
+WW8FlySet::WW8FlySet(SwWW8ImplReader& rReader, const WW8FlyPara* pFW,
+ const WW8SwFlyPara* pFS, bool bGraf)
+ : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
+{
+ if (!rReader.mbNewDoc)
+ Reader::ResetFrmFmtAttrs(*this); // Abstand/Umrandung raus
+ // Position
+ Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
+
+/*Below can all go when we have from left in rtl mode*/
+ SwTwips nXPos = pFS->nXPos;
+ sal_Int16 eHRel = pFS->eHRel;
+ rReader.MiserableRTLGraphicsHack(nXPos, pFS->nWidth, pFS->eHAlign, eHRel);
+/*Above can all go when we have from left in rtl mode*/
+ Put( SwFmtHoriOrient(nXPos, pFS->eHAlign, pFS->eHRel, pFS->bToggelPos ));
+ Put( SwFmtVertOrient( pFS->nYPos, pFS->eVAlign, pFS->eVRel ) );
+
+ if (pFS->nLeMgn || pFS->nRiMgn) // Raender setzen
+ Put(SvxLRSpaceItem(pFS->nLeMgn, pFS->nRiMgn, 0, 0, RES_LR_SPACE));
+
+ if (pFS->nUpMgn || pFS->nLoMgn)
+ Put(SvxULSpaceItem(pFS->nUpMgn, pFS->nLoMgn, RES_UL_SPACE));
+
+ //we no longer need to hack around the header/footer problems
+ Put(SwFmtSurround(pFS->eSurround));
+
+ short aSizeArray[5]={0};
+ rReader.SetFlyBordersShadow(*this,(const WW8_BRC*)pFW->brc,&aSizeArray[0]);
+
+ // der 5. Parameter ist immer 0, daher geht beim Cast nix verloren
+
+ // OD 2004-05-18 #i27767#
+ // --> OD 2004-10-18 #i35017# - constant name has changed
+ Put( SwFmtWrapInfluenceOnObjPos(
+ text::WrapInfluenceOnPosition::ONCE_SUCCESSIVE ) );
+ // <--
+
+ if( !bGraf )
+ {
+ Put( SwFmtAnchor(pFS->eAnchor) );
+ // Groesse einstellen
+
+ //Ordinarily with frames, the border width and spacing is
+ //placed outside the frame, making it larger. With these
+ //types of frames, the left right thickness and space makes
+ //it wider, but the top bottom spacing and border thickness
+ //is placed inside.
+ Put( SwFmtFrmSize( pFS->eHeightFix, pFS->nWidth +
+ aSizeArray[WW8_LEFT] + aSizeArray[WW8_RIGHT],
+ pFS->nHeight));
+ }
+}
+
+// WW8FlySet-ctor fuer zeichengebundene Grafiken
+WW8FlySet::WW8FlySet( SwWW8ImplReader& rReader, const SwPaM* pPaM,
+ const WW8_PIC& rPic, long nWidth, long nHeight )
+ : SfxItemSet(rReader.rDoc.GetAttrPool(),RES_FRMATR_BEGIN,RES_FRMATR_END-1)
+{
+ Init(rReader, pPaM);
+
+ Put(SvxFrameDirectionItem(FRMDIR_HORI_LEFT_TOP, RES_FRAMEDIR));
+
+ short aSizeArray[5]={0};
+ /*
+ If we have set borders then in word the graphic is displaced from the left
+ and top the width of the borders of those sides, and then the shadow
+ itself is drawn to the bottom and right of the displaced graphic. In word
+ the total size is that of the graphic plus the borders, plus the total
+ shadow around all edges, for this translation the top and left shadow
+ region is translated spacing around the graphic to those sides, and the
+ bottom and right shadow size is added to the graphic size.
+ */
+ if (rReader.SetFlyBordersShadow( *this, rPic.rgbrc, &aSizeArray[0]))
+ {
+ Put(SvxLRSpaceItem( aSizeArray[WW8_LEFT], 0, 0, 0, RES_LR_SPACE ) );
+ Put(SvxULSpaceItem( aSizeArray[WW8_TOP], 0, RES_UL_SPACE ));
+ aSizeArray[WW8_RIGHT]*=2;
+ aSizeArray[WW8_BOT]*=2;
+ }
+
+ Put( SwFmtFrmSize( ATT_FIX_SIZE, nWidth+aSizeArray[WW8_LEFT]+
+ aSizeArray[WW8_RIGHT], nHeight+aSizeArray[WW8_TOP]
+ + aSizeArray[WW8_BOT]) );
+}
+
+void WW8FlySet::Init(const SwWW8ImplReader& rReader, const SwPaM* pPaM)
+{
+ if (!rReader.mbNewDoc)
+ Reader::ResetFrmFmtAttrs(*this); // Abstand/Umrandung raus
+
+ Put(SvxLRSpaceItem(RES_LR_SPACE)); //inline writer ole2 objects start with 0.2cm l/r
+ SwFmtAnchor aAnchor(FLY_AS_CHAR);
+
+ aAnchor.SetAnchor(pPaM->GetPoint());
+ Put(aAnchor);
+
+ //The horizontal default is on the baseline, the vertical is centered
+ //around the character center it appears
+ if (rReader.maSectionManager.CurrentSectionIsVertical())
+ Put(SwFmtVertOrient(0, text::VertOrientation::CHAR_CENTER,text::RelOrientation::CHAR));
+ else
+ Put(SwFmtVertOrient(0, text::VertOrientation::TOP, text::RelOrientation::FRAME));
+}
+
+WW8DupProperties::WW8DupProperties(SwDoc &rDoc, SwWW8FltControlStack *pStk)
+ : pCtrlStck(pStk),
+ aChrSet(rDoc.GetAttrPool(), RES_CHRATR_BEGIN, RES_CHRATR_END - 1 ),
+ aParSet(rDoc.GetAttrPool(), RES_PARATR_BEGIN, RES_PARATR_END - 1 )
+{
+ //Close any open character properties and duplicate them inside the
+ //first table cell
+ USHORT nCnt = static_cast< USHORT >(pCtrlStck->Count());
+ for (USHORT i=0; i < nCnt; i++)
+ {
+ const SwFltStackEntry* pEntry = (*pCtrlStck)[ i ];
+ if(pEntry->bLocked)
+ {
+ if (isCHRATR(pEntry->pAttr->Which()))
+ {
+ aChrSet.Put( *pEntry->pAttr );
+
+ }
+ else if (isPARATR(pEntry->pAttr->Which()))
+ {
+ aParSet.Put( *pEntry->pAttr );
+ }
+ }
+ }
+}
+
+void WW8DupProperties::Insert(const SwPosition &rPos)
+{
+ const SfxItemSet *pSet=&aChrSet;
+ for(int i=0;i<2;i++)
+ {
+ if (i==1)
+ pSet = &aParSet;
+
+ if( pSet->Count() )
+ {
+ SfxItemIter aIter( *pSet );
+ const SfxPoolItem* pItem = aIter.GetCurItem();
+ do
+ {
+ pCtrlStck->NewAttr(rPos, *pItem);
+ }while( !aIter.IsAtEnd() && 0 != ( pItem = aIter.NextItem() ) );
+ }
+ }
+}
+
+void SwWW8ImplReader::MoveInsideFly(const SwFrmFmt *pFlyFmt)
+{
+ WW8DupProperties aDup(rDoc,pCtrlStck);
+
+ pCtrlStck->SetAttr(*pPaM->GetPoint(), 0, false);
+
+ // Setze Pam in den FlyFrame
+ const SwFmtCntnt& rCntnt = pFlyFmt->GetCntnt();
+ ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
+ pPaM->GetPoint()->nNode = rCntnt.GetCntntIdx()->GetIndex() + 1;
+ pPaM->GetPoint()->nContent.Assign( pPaM->GetCntntNode(), 0 );
+
+ aDup.Insert(*pPaM->GetPoint());
+}
+
+SwTwips SwWW8ImplReader::MoveOutsideFly(SwFrmFmt *pFlyFmt,
+ const SwPosition &rPos, bool bTableJoin)
+{
+ SwTwips nRetWidth = 0;
+ // Alle Attribute schliessen, da sonst Attribute entstehen koennen,
+ // die aus Flys rausragen
+ WW8DupProperties aDup(rDoc,pCtrlStck);
+ pCtrlStck->SetAttr(*pPaM->GetPoint(), 0, false);
+
+ /*
+ #i1291
+ If this fly frame consists entirely of one table inside a frame
+ followed by an empty paragraph then we want to delete the empty
+ paragraph so as to get the frame to autoshrink to the size of the
+ table to emulate words behaviour closer.
+ */
+ if (bTableJoin)
+ {
+ const SwNodeIndex* pNodeIndex = pFlyFmt->GetCntnt().
+ GetCntntIdx();
+ if (pNodeIndex)
+ {
+ SwNodeIndex aIdx( *pNodeIndex, 1 ),
+ aEnd( *pNodeIndex->GetNode().EndOfSectionNode() );
+
+ if (aIdx < aEnd)
+ {
+ if(aIdx.GetNode().IsTableNode())
+ {
+ SwTableNode *pTable = aIdx.GetNode().GetTableNode();
+ aIdx = *aIdx.GetNode().EndOfSectionNode();
+ aIdx++;
+ if ( (aIdx < aEnd) && aIdx.GetNode().IsTxtNode() )
+ {
+ SwTxtNode *pNd = aIdx.GetNode().GetTxtNode();
+ aIdx++;
+ if (aIdx == aEnd && pNd && !pNd->GetTxt().Len())
+ {
+ rDoc.DelFullPara( *pPaM );
+
+ SwTable& rTable = pTable->GetTable();
+ SwFrmFmt* pTblFmt = rTable.GetFrmFmt();
+
+ if (pTblFmt)
+ {
+ SwFmtFrmSize aSize = pTblFmt->GetFrmSize();
+ aSize.SetHeightSizeType(ATT_MIN_SIZE);
+ aSize.SetHeight(MINLAY);
+ pFlyFmt->SetFmtAttr(aSize);
+ pTblFmt->SetFmtAttr(SwFmtHoriOrient(0,text::HoriOrientation::FULL));
+ nRetWidth = aSize.GetWidth();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ *pPaM->GetPoint() = rPos;
+ aDup.Insert(*pPaM->GetPoint());
+ return nRetWidth;
+}
+
+WW8FlyPara *SwWW8ImplReader::ConstructApo(const ApoTestResults &rApo,
+ const WW8_TablePos *pTabPos)
+{
+ WW8FlyPara *pRet = 0;
+ ASSERT(rApo.HasFrame() || pTabPos,
+ "If no frame found, *MUST* be in a table");
+
+ pRet = new WW8FlyPara(bVer67, rApo.mpStyleApo);
+
+ // APO-Parameter ermitteln und Test auf bGrafApo
+ if (rApo.HasFrame())
+ pRet->ReadFull(rApo.mpSprm29, this);
+
+ pRet->ApplyTabPos(pTabPos);
+
+ if (pRet->IsEmpty())
+ delete pRet, pRet = 0;
+ return pRet;
+}
+
+bool SwWW8ImplReader::IsDropCap()
+{
+ // Find the DCS (Drop Cap Specifier) for the paragraph
+ // if does not exist or if the first three bits are 0
+ // then there is no dropcap on the paragraph
+ WW8PLCFx_Cp_FKP *pPap = pPlcxMan ? pPlcxMan->GetPapPLCF() : 0;
+ if (pPap)
+ {
+ const BYTE *pDCS;
+ if (bVer67)
+ pDCS = pPap->HasSprm(46);
+ else
+ pDCS = pPlcxMan->GetPapPLCF()->HasSprm(0x442C);
+ if(pDCS)
+ {
+ short nDCS = SVBT16ToShort( pDCS );
+ if((nDCS | 7) != 0)
+ return true;
+ }
+ }
+ return false;
+}
+
+bool SwWW8ImplReader::StartApo(const ApoTestResults &rApo,
+ const WW8_TablePos *pTabPos)
+{
+ if (0 == (pWFlyPara = ConstructApo(rApo, pTabPos)))
+ return false;
+
+ // --> OD 2007-07-03 #148498#
+ // <WW8SwFlyPara> constructor has changed - new 4th parameter
+ // containing WW8 page top margin.
+ pSFlyPara = new WW8SwFlyPara( *pPaM, *this, *pWFlyPara,
+ maSectionManager.GetWWPageTopMargin(),
+ maSectionManager.GetPageLeft(),
+ maSectionManager.GetTextAreaWidth(),
+ nIniFlyDx, nIniFlyDy);
+ // <--
+
+ // If this paragraph is a Dropcap set the flag and we will deal with it later
+ if (IsDropCap())
+ {
+ bDropCap = true;
+ pAktItemSet = new SfxItemSet( rDoc.GetAttrPool(), RES_CHRATR_BEGIN, RES_PARATR_END - 1 );
+ return false;
+ }
+
+ if( !pWFlyPara->bGrafApo )
+ {
+
+ // Innerhalb des GrafApo muessen Textattribute ignoriert werden, da
+ // sie sonst auf den folgenden Zeilen landen. Der Rahmen wird nur
+ // eingefuegt, wenn er *nicht* nur zum Positionieren einer einzelnen
+ // Grafik dient. Ist es ein Grafik-Rahmen, dann werden pWFlyPara und
+ // pSFlyPara behalten und die
+ // daraus resultierenden Attribute beim Einfuegen der Grafik auf die
+ // Grafik angewendet.
+
+ WW8FlySet aFlySet(*this, pWFlyPara, pSFlyPara, false);
+
+ pSFlyPara->pFlyFmt = rDoc.MakeFlySection( pSFlyPara->eAnchor,
+ pPaM->GetPoint(), &aFlySet );
+ ASSERT(pSFlyPara->pFlyFmt->GetAnchor().GetAnchorId() ==
+ pSFlyPara->eAnchor, "Not the anchor type requested!");
+
+ if (pSFlyPara->pFlyFmt)
+ {
+ if (!pDrawModel)
+ GrafikCtor();
+
+ SdrObject* pOurNewObject = CreateContactObject(pSFlyPara->pFlyFmt);
+ pWWZOrder->InsertTextLayerObject(pOurNewObject);
+ }
+
+ if (FLY_AS_CHAR != pSFlyPara->eAnchor)
+ {
+ pAnchorStck->AddAnchor(*pPaM->GetPoint(),pSFlyPara->pFlyFmt);
+ }
+
+ // merke Pos im Haupttext
+ pSFlyPara->pMainTextPos = new SwPosition( *pPaM->GetPoint() );
+
+ //remove fltanchors, otherwise they will be closed inside the
+ //frame, which makes no sense, restore them after the frame is
+ //closed
+ pSFlyPara->pOldAnchorStck = pAnchorStck;
+ pAnchorStck = new SwWW8FltAnchorStack(&rDoc, nFieldFlags);
+
+ MoveInsideFly(pSFlyPara->pFlyFmt);
+
+ // 1) ReadText() wird nicht wie beim W4W-Reader rekursiv aufgerufen,
+ // da die Laenge des Apo zu diesen Zeitpunkt noch nicht feststeht,
+ // ReadText() diese Angabe aber braucht.
+ // 2) Der CtrlStck wird nicht neu erzeugt.
+ // die Char-Attribute laufen weiter ( AErger mit SW-Attributen )
+ // Paraattribute muessten am Ende jeden Absatzes zurueckgesetzt
+ // sein, d.h. es duerften am Absatzende keine Paraattribute
+ // auf dem Stack liegen
+ }
+ return true;
+}
+
+void wwSectionManager::JoinNode(const SwPosition &rPos, const SwNode &rNode)
+{
+ if ((!maSegments.empty()) && (maSegments.back().maStart == rPos.nNode))
+ maSegments.back().maStart = SwNodeIndex(rNode);
+}
+
+bool SwWW8ImplReader::JoinNode(SwPaM &rPam, bool bStealAttr)
+{
+ bool bRet = false;
+ rPam.GetPoint()->nContent = 0; // an den Anfang der Zeile gehen
+
+ SwNodeIndex aPref(rPam.GetPoint()->nNode, -1);
+
+ if (SwTxtNode* pNode = aPref.GetNode().GetTxtNode())
+ {
+ maSectionManager.JoinNode(*rPam.GetPoint(), aPref.GetNode());
+ rPam.GetPoint()->nNode = aPref;
+ rPam.GetPoint()->nContent.Assign(pNode, pNode->GetTxt().Len());
+ if (bStealAttr)
+ pCtrlStck->StealAttr(rPam.GetPoint());
+
+ pNode->JoinNext();
+
+ bRet = true;
+ }
+ return bRet;
+}
+
+void SwWW8ImplReader::StopApo()
+{
+ ASSERT(pWFlyPara, "no pWFlyPara to close");
+ if (!pWFlyPara)
+ return;
+ if (pWFlyPara->bGrafApo)
+ {
+ // Grafik-Rahmen, der *nicht* eingefuegt wurde leeren Absatz incl.
+ // Attributen entfernen
+ JoinNode(*pPaM, true);
+
+ }
+ else
+ {
+ if (!pSFlyPara->pMainTextPos || !pWFlyPara)
+ {
+ ASSERT( pSFlyPara->pMainTextPos, "StopApo: pMainTextPos ist 0" );
+ ASSERT( pWFlyPara, "StopApo: pWFlyPara ist 0" );
+ return;
+ }
+
+ /*
+ #104920#
+ What we are doing with this temporary nodeindex is as follows: The
+ stack of attributes normally only places them into the document when
+ the current insertion point has passed them by. Otherwise the end
+ point of the attribute gets pushed along with the insertion point. The
+ insertion point is moved and the properties commited during
+ MoveOutsideFly. We also may want to remove the final paragraph in the
+ frame, but we need to wait until the properties for that frame text
+ have been commited otherwise they will be lost. So we first get a
+ handle to the last the filter inserted. After the attributes are
+ commited, if that paragraph exists we join it with the para after it
+ that comes with the frame by default so that as normal we don't end up
+ with one more paragraph than we wanted.
+ */
+ SwNodeIndex aPref(pPaM->GetPoint()->nNode, -1);
+
+ SwTwips nNewWidth =
+ MoveOutsideFly(pSFlyPara->pFlyFmt, *pSFlyPara->pMainTextPos);
+ if (nNewWidth)
+ pSFlyPara->BoxUpWidth(nNewWidth);
+
+ Color aBg(0xFE, 0xFF, 0xFF, 0xFF); //Transparent by default
+
+ if (SwTxtNode* pNd = aPref.GetNode().GetTxtNode())
+ {
+ /*
+ #i582#/#114238#
+ Take the last paragraph background colour and fill the frame with
+ it. Otherwise, make it transparent, this appears to be how MSWord
+ works
+ */
+ const SfxPoolItem &rItm = pNd->SwCntntNode::GetAttr(RES_BACKGROUND);
+ const SvxBrushItem &rBrush = (const SvxBrushItem&)(rItm);
+ if (rBrush.GetColor().GetColor() != COL_AUTO)
+ aBg = rBrush.GetColor();
+
+ //Get rid of extra empty paragraph
+ pNd->JoinNext();
+ }
+
+ pSFlyPara->pFlyFmt->SetFmtAttr(SvxBrushItem(aBg, RES_BACKGROUND));
+
+ DeleteAnchorStk();
+ pAnchorStck = pSFlyPara->pOldAnchorStck;
+
+ // Ist die Fly-Breite durch eine innenliegende Grafik vergroessert
+ // worden ( bei automatischer Breite des Flys ), dann muss die Breite
+ // des SW-Flys entsprechend umgesetzt werden, da der SW keine
+ // automatische Breite kennt.
+ if( pSFlyPara->nNewNettoWidth > MINFLY ) // BoxUpWidth ?
+ {
+ long nW = pSFlyPara->nNewNettoWidth;
+ nW += pSFlyPara->nWidth - pSFlyPara->nNettoWidth; // Rand dazu
+ pSFlyPara->pFlyFmt->SetFmtAttr(
+ SwFmtFrmSize( pSFlyPara->eHeightFix, nW, pSFlyPara->nHeight ) );
+ }
+ /*
+ #83307# Word set *no* width meaning its an automatic width. The
+ SwFlyPara reader will have already set a fallback width of the
+ printable regions width, so we should reuse it. Despite the related
+ problems with layout addressed with a hack in WW8FlyPara's constructor
+ #i27204# Added AutoWidth setting. Left the old CalculateFlySize in place
+ so that if the user unselects autowidth, the width doesn't max out
+ */
+ else if( !pWFlyPara->nSp28 )
+ {
+ using namespace sw::util;
+ SfxItemSet aFlySet( pSFlyPara->pFlyFmt->GetAttrSet() );
+
+ SwFmtFrmSize aSize(ItemGet<SwFmtFrmSize>(aFlySet, RES_FRM_SIZE));
+
+ aFlySet.ClearItem(RES_FRM_SIZE);
+
+ CalculateFlySize(aFlySet, pSFlyPara->pMainTextPos->nNode,
+ pSFlyPara->nWidth);
+
+ nNewWidth = ItemGet<SwFmtFrmSize>(aFlySet, RES_FRM_SIZE).GetWidth();
+
+ aSize.SetWidth(nNewWidth);
+ aSize.SetWidthSizeType(ATT_VAR_SIZE);
+
+ pSFlyPara->pFlyFmt->SetFmtAttr(aSize);
+ }
+
+ delete pSFlyPara->pMainTextPos, pSFlyPara->pMainTextPos = 0;
+
+// Damit die Frames bei Einfuegen in existierendes Doc erzeugt werden,
+// wird in fltshell.cxx beim Setzen des FltAnchor-Attributes
+// pFlyFrm->MakeFrms() gerufen
+
+ }
+
+ //#i8062#
+ if (pSFlyPara && pSFlyPara->pFlyFmt)
+ pFmtOfJustInsertedApo = pSFlyPara->pFlyFmt;
+
+ DELETEZ( pSFlyPara );
+ DELETEZ( pWFlyPara );
+}
+
+// TestSameApo() beantwortet die Frage, ob es dasselbe APO oder ein neues ist
+bool SwWW8ImplReader::TestSameApo(const ApoTestResults &rApo,
+ const WW8_TablePos *pTabPos)
+{
+ if( !pWFlyPara )
+ {
+ ASSERT( pWFlyPara, " Wo ist mein pWFlyPara ? " );
+ return true;
+ }
+
+ // Es muss ein kompletter Vergleich ( ausser Borders ) stattfinden, um
+ // alle Kombinationen Style / Hart richtig einzuordnen. Deshalb wird ein
+ // temporaerer WW8FlyPara angelegt ( abh. ob Style oder nicht ), darauf
+ // die harten Attrs angewendet, und dann verglichen
+
+ // Zum Vergleich
+ WW8FlyPara aF(bVer67, rApo.mpStyleApo);
+ // WWPara fuer akt. Para
+ if (rApo.HasFrame())
+ aF.Read(rApo.mpSprm29, pPlcxMan->GetPapPLCF());
+ aF.ApplyTabPos(pTabPos);
+
+ return aF == *pWFlyPara;
+}
+
+/***************************************************************************
+# Attribut - Verwaltung
+#**************************************************************************/
+
+void SwWW8ImplReader::NewAttr( const SfxPoolItem& rAttr,
+ const bool bFirstLineOfStSet,
+ const bool bLeftIndentSet )
+{
+ if( !bNoAttrImport ) // zum Ignorieren von Styles beim Doc-Einfuegen
+ {
+ if (pAktColl)
+ {
+ ASSERT(rAttr.Which() != RES_FLTR_REDLINE, "redline in style!");
+ pAktColl->SetFmtAttr(rAttr);
+ }
+ else if (pAktItemSet)
+ {
+ pAktItemSet->Put(rAttr);
+ }
+ else if (rAttr.Which() == RES_FLTR_REDLINE)
+ {
+ mpRedlineStack->open(*pPaM->GetPoint(), rAttr);
+ }
+ else
+ {
+ pCtrlStck->NewAttr(*pPaM->GetPoint(), rAttr);
+ // --> OD 2010-05-06 #i103711#
+ if ( bFirstLineOfStSet )
+ {
+ const SwNode* pNd = &(pPaM->GetPoint()->nNode.GetNode());
+ maTxtNodesHavingFirstLineOfstSet.insert( pNd );
+ }
+ // <--
+ // --> OD 2010-05-11 #i105414#
+ if ( bLeftIndentSet )
+ {
+ const SwNode* pNd = &(pPaM->GetPoint()->nNode.GetNode());
+ maTxtNodesHavingLeftIndentSet.insert( pNd );
+ }
+ // <--
+ }
+
+ if (mpPostProcessAttrsInfo && mpPostProcessAttrsInfo->mbCopy)
+ mpPostProcessAttrsInfo->mItemSet.Put(rAttr);
+ }
+}
+
+// holt Attribut aus der FmtColl / Stack / Doc
+const SfxPoolItem* SwWW8ImplReader::GetFmtAttr( USHORT nWhich )
+{
+ const SfxPoolItem* pRet = 0;
+ if (pAktColl)
+ pRet = &(pAktColl->GetFmtAttr(nWhich));
+ else if (pAktItemSet)
+ {
+ pRet = pAktItemSet->GetItem(nWhich);
+ if (!pRet)
+ pRet = pStandardFmtColl ? &(pStandardFmtColl->GetFmtAttr(nWhich)) : 0;
+ if (!pRet)
+ pRet = &rDoc.GetAttrPool().GetDefaultItem(nWhich);
+ }
+ else if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
+ {
+ pRet = pCtrlStck->GetStackAttr(*pPaM->GetPoint(), nWhich);
+ if (!pRet)
+ {
+ if (nAktColl < nColls && pCollA[nAktColl].pFmt &&
+ pCollA[nAktColl].bColl)
+ {
+ pRet = &(pCollA[nAktColl].pFmt->GetFmtAttr(nWhich));
+ }
+ }
+ if (!pRet)
+ pRet = pStandardFmtColl ? &(pStandardFmtColl->GetFmtAttr(nWhich)) : 0;
+ if (!pRet)
+ pRet = &rDoc.GetAttrPool().GetDefaultItem(nWhich);
+ }
+ else
+ pRet = pCtrlStck->GetFmtAttr(*pPaM->GetPoint(), nWhich);
+ return pRet;
+}
+
+/***************************************************************************
+# eigentliche Attribute
+#
+# Die Methoden erhalten die Token-Id und die Laenge der noch folgenden
+# Parameter gemaess Tabelle in WWScan.cxx als Parameter
+#**************************************************************************/
+
+/***************************************************************************
+# Spezial WW - Attribute
+#**************************************************************************/
+
+void SwWW8ImplReader::Read_Special(USHORT, const BYTE* pData, short nLen)
+{
+ if( nLen < 0 )
+ {
+ bSpec = false;
+ return;
+ }
+ bSpec = ( *pData != 0 );
+}
+
+// Read_Obj wird fuer fObj und fuer fOle2 benutzt !
+void SwWW8ImplReader::Read_Obj(USHORT , const BYTE* pData, short nLen)
+{
+ if( nLen < 0 )
+ bObj = false;
+ else
+ {
+ bObj = 0 != *pData;
+
+ if( bObj && nPicLocFc && bEmbeddObj )
+ nObjLocFc = nPicLocFc;
+ }
+}
+
+void SwWW8ImplReader::Read_PicLoc(USHORT , const BYTE* pData, short nLen )
+{
+ if( nLen < 0 )
+ {
+ nPicLocFc = 0;
+ bSpec = false; // Stimmt das immer ?
+ }
+ else
+ {
+ nPicLocFc = SVBT32ToUInt32( pData );
+ bSpec = true;
+
+ if( bObj && nPicLocFc && bEmbeddObj )
+ nObjLocFc = nPicLocFc;
+ }
+}
+
+void SwWW8ImplReader::Read_POutLvl(USHORT, const BYTE* pData, short nLen )
+{
+ if (pAktColl && (0 < nLen))
+ {
+ if (SwWW8StyInf* pSI = GetStyle(nAktColl))
+ {
+ pSI->nOutlineLevel = static_cast< BYTE >(
+ ( (1 <= pSI->GetWWStyleId()) && (9 >= pSI->GetWWStyleId()) )
+ ? pSI->GetWWStyleId()-1
+ : (pData ? *pData : 0) );
+ }
+ }
+}
+
+void SwWW8ImplReader::Read_Symbol(USHORT, const BYTE* pData, short nLen )
+{
+ if( !bIgnoreText )
+ {
+ if( nLen < 0 )
+ {
+ //otherwise disable after we print the char
+ if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_FONT );
+ bSymbol = false;
+ }
+ else
+ {
+ // Make new Font-Atribut
+ // (will be closed in SwWW8ImplReader::ReadChars() )
+
+ //Will not be added to the charencoding stack, for styles the real
+ //font setting will be put in as the styles charset, and for plain
+ //text encoding for symbols is moot. Drawing boxes will check bSymbol
+ //themselves so they don't need to add it to the stack either.
+ if (SetNewFontAttr(SVBT16ToShort( pData ), false, RES_CHRATR_FONT))
+ {
+ if( bVer67 )
+ {
+ cSymbol = ByteString::ConvertToUnicode(
+ *(sal_Char*)(pData+2), RTL_TEXTENCODING_MS_1252 );
+ }
+ else
+ cSymbol = SVBT16ToShort( pData+2 );
+ bSymbol = true;
+ }
+ }
+ }
+}
+
+SwWW8StyInf *SwWW8ImplReader::GetStyle(USHORT nColl) const
+{
+ return nColl < nColls ? &pCollA[nColl] : 0;
+}
+
+/***************************************************************************
+# Zeichen - Attribute
+#**************************************************************************/
+
+// Read_BoldUsw fuer Italic, Bold, Kapitaelchen, Versalien, durchgestrichen,
+// Contour und Shadow
+void SwWW8ImplReader::Read_BoldUsw( USHORT nId, const BYTE* pData, short nLen )
+{
+ const int nContigiousWestern = 8;
+ const int nWestern = nContigiousWestern + 1;
+ const int nEastern = 2;
+ const int nIds = nWestern + nEastern;
+ static const USHORT nEndIds[ nIds ] =
+ {
+ RES_CHRATR_WEIGHT, RES_CHRATR_POSTURE,
+ RES_CHRATR_CROSSEDOUT, RES_CHRATR_CONTOUR,
+ RES_CHRATR_SHADOWED, RES_CHRATR_CASEMAP,
+ RES_CHRATR_CASEMAP, RES_CHRATR_HIDDEN,
+
+ RES_CHRATR_CROSSEDOUT,
+
+ RES_CHRATR_CJK_WEIGHT, RES_CHRATR_CJK_POSTURE
+ };
+
+ ww::WordVersion eVersion = pWwFib->GetFIBVersion();
+
+ BYTE nI;
+ // die Attribut-Nr fuer "doppelt durchgestrichen" tanzt aus der Reihe
+ if (0x2A53 == nId)
+ nI = nContigiousWestern; // The out of sequence western id
+ else
+ {
+ // The contigious western ids
+ if (eVersion <= ww::eWW2)
+ nI = static_cast< BYTE >(nId - 60);
+ else if (eVersion < ww::eWW8)
+ nI = static_cast< BYTE >(nId - 85);
+ else
+ nI = static_cast< BYTE >(nId - 0x0835);
+ }
+
+ sal_uInt16 nMask = 1 << nI;
+
+ if (nLen < 0)
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nI ] );
+ // reset the CJK Weight and Posture, because they are the same as their
+ // western equivalents in word
+ if (nI < 2)
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), nEndIds[ nWestern + nI ] );
+ pCtrlStck->SetToggleAttr(nI, false);
+ return;
+ }
+ // Wert: 0 = Aus, 1 = An, 128 = Wie Style, 129 entgegen Style
+ bool bOn = *pData & 1;
+ SwWW8StyInf* pSI = GetStyle(nAktColl);
+ if (pPlcxMan && eVersion > ww::eWW2)
+ {
+ const BYTE *pCharIstd =
+ pPlcxMan->GetChpPLCF()->HasSprm(bVer67 ? 80 : 0x4A30);
+ if (pCharIstd)
+ pSI = GetStyle(SVBT16ToShort(pCharIstd));
+ }
+
+ if( pAktColl ) // StyleDef -> Flags merken
+ {
+ if (pSI)
+ {
+ // The style based on has Bit 7 set ?
+ if (
+ pSI->nBase < nColls && (*pData & 0x80) &&
+ (pCollA[pSI->nBase].n81Flags & nMask)
+ )
+ {
+ bOn = !bOn; // umdrehen
+ }
+
+ if (bOn)
+ pSI->n81Flags |= nMask; // Flag setzen
+ else
+ pSI->n81Flags &= ~nMask; // Flag loeschen
+ }
+ }
+ else
+ {
+
+ // im Text -> Flags abfragen
+ if( *pData & 0x80 ) // Bit 7 gesetzt ?
+ {
+ if (pSI && pSI->n81Flags & nMask) // und in StyleDef an ?
+ bOn = !bOn; // dann invertieren
+ // am Stack vermerken, das dieses ein Toggle-Attribut ist
+ pCtrlStck->SetToggleAttr(nI, true);
+ }
+ }
+
+ SetToggleAttr( nI, bOn );
+}
+
+void SwWW8ImplReader::Read_Bidi(USHORT, const BYTE*, short nLen)
+{
+ if (nLen > 0)
+ bBidi = true;
+ else
+ bBidi = false;
+}
+
+// Read_BoldUsw for BiDi Italic, Bold
+void SwWW8ImplReader::Read_BoldBiDiUsw(USHORT nId, const BYTE* pData,
+ short nLen)
+{
+ static const USHORT nEndIds[2] =
+ {
+ RES_CHRATR_CTL_WEIGHT, RES_CHRATR_CTL_POSTURE,
+ };
+
+ BYTE nI;
+ ww::WordVersion eVersion = pWwFib->GetFIBVersion();
+ if (eVersion <= ww::eWW2)
+ nI = static_cast< BYTE >(nId - 80);
+ else if (eVersion < ww::eWW8)
+ nI = static_cast< BYTE >(nId - 111);
+ else
+ nI = static_cast< BYTE >(nId - 0x085C);
+
+ ASSERT(nI <= 1, "not happening");
+ if (nI > 1)
+ return;
+
+ sal_uInt16 nMask = 1 << nI;
+
+ if( nLen < 0 )
+ {
+ pCtrlStck->SetAttr(*pPaM->GetPoint(),nEndIds[nI]);
+ pCtrlStck->SetToggleBiDiAttr(nI, false);
+ return;
+ }
+ bool bOn = *pData & 1;
+ SwWW8StyInf* pSI = GetStyle(nAktColl);
+ if (pPlcxMan)
+ {
+ const BYTE *pCharIstd =
+ pPlcxMan->GetChpPLCF()->HasSprm(bVer67 ? 80 : 0x4A30);
+ if (pCharIstd)
+ pSI = GetStyle(SVBT16ToShort(pCharIstd));
+ }
+
+ if (pAktColl && eVersion > ww::eWW2) // StyleDef -> Flags merken
+ {
+ if (pSI)
+ {
+ if( pSI->nBase < nColls // Style Based on
+ && ( *pData & 0x80 ) // Bit 7 gesetzt ?
+ && ( pCollA[pSI->nBase].n81BiDiFlags & nMask ) ) // BasisMaske ?
+ bOn = !bOn; // umdrehen
+
+ if( bOn )
+ pSI->n81BiDiFlags |= nMask; // Flag setzen
+ else
+ pSI->n81BiDiFlags &= ~nMask; // Flag loeschen
+ }
+ }
+ else
+ {
+
+ // im Text -> Flags abfragen
+ if (*pData & 0x80) // Bit 7 gesetzt ?
+ {
+ if (pSI && pSI->n81BiDiFlags & nMask) // und in StyleDef an ?
+ bOn = !bOn; // dann invertieren
+ // am Stack vermerken, das dieses ein Toggle-Attribut ist
+ pCtrlStck->SetToggleBiDiAttr(nI, true);
+ }
+ }
+
+ SetToggleBiDiAttr(nI, bOn);
+}
+
+void SwWW8ImplReader::SetToggleBiDiAttr(BYTE nAttrId, bool bOn)
+{
+ switch (nAttrId)
+ {
+ case 0:
+ {
+ SvxWeightItem aAttr( bOn ? WEIGHT_BOLD : WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
+ aAttr.SetWhich( RES_CHRATR_CTL_WEIGHT );
+ NewAttr( aAttr );
+ }
+ break;
+ case 1:
+ {
+ SvxPostureItem aAttr( bOn ? ITALIC_NORMAL : ITALIC_NONE, RES_CHRATR_POSTURE );
+ aAttr.SetWhich( RES_CHRATR_CTL_POSTURE );
+ NewAttr( aAttr );
+ }
+ break;
+ default:
+ ASSERT(!this, "Unhandled unknown bidi toggle attribute");
+ break;
+
+ }
+}
+
+void SwWW8ImplReader::SetToggleAttr(BYTE nAttrId, bool bOn)
+{
+ switch (nAttrId)
+ {
+ case 0:
+ {
+ SvxWeightItem aAttr( bOn ? WEIGHT_BOLD : WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
+ NewAttr( aAttr );
+ aAttr.SetWhich( RES_CHRATR_CJK_WEIGHT );
+ NewAttr( aAttr );
+ }
+ break;
+ case 1:
+ {
+ SvxPostureItem aAttr( bOn ? ITALIC_NORMAL : ITALIC_NONE, RES_CHRATR_POSTURE );
+ NewAttr( aAttr );
+ aAttr.SetWhich( RES_CHRATR_CJK_POSTURE );
+ NewAttr( aAttr );
+ }
+ break;
+ case 2:
+ NewAttr(SvxCrossedOutItem(bOn ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT));
+ break;
+ case 3:
+ NewAttr( SvxContourItem( bOn, RES_CHRATR_CONTOUR ) );
+ break;
+ case 4:
+ NewAttr( SvxShadowedItem( bOn, RES_CHRATR_SHADOWED ) );
+ break;
+ case 5:
+ NewAttr( SvxCaseMapItem( bOn ? SVX_CASEMAP_KAPITAELCHEN
+ : SVX_CASEMAP_NOT_MAPPED, RES_CHRATR_CASEMAP ) );
+ break;
+ case 6:
+ NewAttr( SvxCaseMapItem( bOn ? SVX_CASEMAP_VERSALIEN
+ : SVX_CASEMAP_NOT_MAPPED, RES_CHRATR_CASEMAP ) );
+ break;
+ case 7:
+ NewAttr(SvxCharHiddenItem(bOn, RES_CHRATR_HIDDEN));
+ break;
+ case 8:
+ NewAttr( SvxCrossedOutItem( bOn ? STRIKEOUT_DOUBLE
+ : STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT ) );
+ break;
+ default:
+ ASSERT(!this, "Unhandled unknown toggle attribute");
+ break;
+ }
+}
+
+void SwWW8ImplReader::_ChkToggleAttr( USHORT nOldStyle81Mask,
+ USHORT nNewStyle81Mask )
+{
+ USHORT i = 1, nToggleAttrFlags = pCtrlStck->GetToggleAttrFlags();
+ for (BYTE n = 0; n < 7; ++n, i <<= 1)
+ {
+ if (
+ (i & nToggleAttrFlags) &&
+ ((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
+ )
+ {
+ SetToggleAttr(n, (i & nOldStyle81Mask));
+ }
+ }
+}
+
+void SwWW8ImplReader::_ChkToggleBiDiAttr( USHORT nOldStyle81Mask,
+ USHORT nNewStyle81Mask )
+{
+ USHORT i = 1, nToggleAttrFlags = pCtrlStck->GetToggleBiDiAttrFlags();
+ for (BYTE n = 0; n < 7; ++n, i <<= 1)
+ {
+ if (
+ (i & nToggleAttrFlags) &&
+ ((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
+ )
+ {
+ SetToggleBiDiAttr(n, (i & nOldStyle81Mask));
+ }
+ }
+}
+
+void SwWW8ImplReader::Read_SubSuper( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 ){
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
+ return;
+ }
+
+ short nEs;
+ BYTE nProp;
+ switch( *pData )
+ {
+ case 1:
+ nEs = DFLT_ESC_AUTO_SUPER;
+ nProp = DFLT_ESC_PROP;
+ break;
+ case 2:
+ nEs = DFLT_ESC_AUTO_SUB;
+ nProp = DFLT_ESC_PROP;
+ break;
+ default:
+ nEs = 0;
+ nProp = 100;
+ break;
+ }
+ NewAttr( SvxEscapementItem( nEs, nProp, RES_CHRATR_ESCAPEMENT ) );
+}
+
+SwFrmFmt *SwWW8ImplReader::ContainsSingleInlineGraphic(const SwPaM &rRegion)
+{
+ /*
+ #92489# & #92946#
+ For inline graphics and objects word has a hacked in feature to use
+ subscripting to force the graphic into a centered position on the line, so
+ we must check when applying sub/super to see if it the subscript range
+ contains only a single graphic, and if that graphic is anchored as
+ FLY_AS_CHAR and then we can change its anchoring to centered in the line.
+ */
+ SwFrmFmt *pRet=0;
+ SwNodeIndex aBegin(rRegion.Start()->nNode);
+ xub_StrLen nBegin(rRegion.Start()->nContent.GetIndex());
+ SwNodeIndex aEnd(rRegion.End()->nNode);
+ xub_StrLen nEnd(rRegion.End()->nContent.GetIndex());
+ const SwTxtNode* pTNd;
+ const SwTxtAttr* pTFlyAttr;
+ if (
+ aBegin == aEnd && nBegin == nEnd - 1 &&
+ 0 != (pTNd = aBegin.GetNode().GetTxtNode()) &&
+ 0 != (pTFlyAttr = pTNd->GetTxtAttrForCharAt(nBegin, RES_TXTATR_FLYCNT))
+ )
+ {
+ const SwFmtFlyCnt& rFly = pTFlyAttr->GetFlyCnt();
+ SwFrmFmt *pFlyFmt = rFly.GetFrmFmt();
+ if (pFlyFmt &&
+ (FLY_AS_CHAR == pFlyFmt->GetAnchor().GetAnchorId()))
+ {
+ pRet = pFlyFmt;
+ }
+ }
+ return pRet;
+}
+
+bool SwWW8ImplReader::ConvertSubToGraphicPlacement()
+{
+ /*
+ #92489# & #92946#
+ For inline graphics and objects word has a hacked in feature to use
+ subscripting to force the graphic into a centered position on the line, so
+ we must check when applying sub/super to see if it the subscript range
+ contains only a single graphic, and if that graphic is anchored as
+ FLY_AS_CHAR and then we can change its anchoring to centered in the line.
+ */
+ bool bIsGraphicPlacementHack = false;
+ USHORT nPos;
+ if (pCtrlStck->GetFmtStackAttr(RES_CHRATR_ESCAPEMENT, &nPos))
+ {
+ SwPaM aRegion(*pPaM->GetPoint());
+
+ SwFltStackEntry aEntry = *((*pCtrlStck)[nPos]);
+ aEntry.SetEndPos(*pPaM->GetPoint());
+
+ SwFrmFmt *pFlyFmt = 0;
+ if (
+ aEntry.MakeRegion(&rDoc,aRegion,false) &&
+ 0 != (pFlyFmt = ContainsSingleInlineGraphic(aRegion))
+ )
+ {
+ pCtrlStck->DeleteAndDestroy(nPos);
+ pFlyFmt->SetFmtAttr(SwFmtVertOrient(0, text::VertOrientation::CHAR_CENTER, text::RelOrientation::CHAR));
+ bIsGraphicPlacementHack = true;
+ }
+ }
+ return bIsGraphicPlacementHack;
+}
+
+void SwWW8ImplReader::Read_SubSuperProp( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 )
+ {
+ if (!ConvertSubToGraphicPlacement())
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
+ return;
+ }
+
+ ww::WordVersion eVersion = pWwFib->GetFIBVersion();
+
+ // Font-Position in HalfPoints
+ short nPos = eVersion <= ww::eWW2 ? *pData : SVBT16ToShort( pData );
+ INT32 nPos2 = nPos * ( 10 * 100 ); // HalfPoints in 100 * tw
+ const SvxFontHeightItem* pF
+ = (const SvxFontHeightItem*)GetFmtAttr(RES_CHRATR_FONTSIZE);
+ ASSERT(pF, "Expected to have the fontheight available here");
+
+ // #i59022: Check ensure nHeight != 0. Div by zero otherwise.
+ INT32 nHeight = 240;
+ if (pF != NULL && pF->GetHeight() != 0)
+ nHeight = pF->GetHeight();
+ nPos2 /= nHeight; // ... nun in % ( gerundet )
+ if( nPos2 > 100 ) // zur Sicherheit
+ nPos2 = 100;
+ if( nPos2 < -100 )
+ nPos2 = -100;
+ SvxEscapementItem aEs( (short)nPos2, 100, RES_CHRATR_ESCAPEMENT );
+ NewAttr( aEs );
+}
+
+void SwWW8ImplReader::Read_Underline( USHORT, const BYTE* pData, short nLen )
+{
+ FontUnderline eUnderline = UNDERLINE_NONE;
+ bool bWordLine = false;
+ if( pData )
+ {
+ // Parameter: 0 = none, 1 = single, 2 = by Word,
+ // 3 = double, 4 = dotted, 5 = hidden
+ // 6 = thick, 7 = dash, 8 = dot(not used)
+ // 9 = dotdash 10 = dotdotdash 11 = wave
+
+
+ // pruefe auf Sonderfall "fett+unterstrichen"
+ bool bAlsoBold = /*( 6 == b )*/ false;
+ // erst mal ggfs. *bold* einschalten!
+ if( bAlsoBold )
+ {
+ BYTE nOn = 1;
+ Read_BoldUsw( 0x0835, &nOn, nLen );
+ eUnderline = UNDERLINE_SINGLE;
+ }
+ else
+ {
+ switch( *pData )
+ {
+ case 2: bWordLine = true; // no break;
+ case 1: eUnderline = (FontUnderline)UNDERLINE_SINGLE; break;
+ case 3: eUnderline = (FontUnderline)UNDERLINE_DOUBLE; break;
+ case 4: eUnderline = (FontUnderline)UNDERLINE_DOTTED; break;
+ case 7: eUnderline = (FontUnderline)UNDERLINE_DASH; break;
+ case 9: eUnderline = (FontUnderline)UNDERLINE_DASHDOT; break;
+ case 10:eUnderline = (FontUnderline)UNDERLINE_DASHDOTDOT; break;
+ case 6: eUnderline = (FontUnderline)UNDERLINE_BOLD; break;
+ case 11:eUnderline = (FontUnderline)UNDERLINE_WAVE; break;
+ case 20:eUnderline = (FontUnderline)UNDERLINE_BOLDDOTTED; break;
+ case 23:eUnderline = (FontUnderline)UNDERLINE_BOLDDASH; break;
+ case 39:eUnderline = (FontUnderline)UNDERLINE_LONGDASH; break;
+ case 55:eUnderline = (FontUnderline)UNDERLINE_BOLDLONGDASH; break;
+ case 25:eUnderline = (FontUnderline)UNDERLINE_BOLDDASHDOT; break;
+ case 26:eUnderline = (FontUnderline)UNDERLINE_BOLDDASHDOTDOT;break;
+ case 27:eUnderline = (FontUnderline)UNDERLINE_BOLDWAVE; break;
+ case 43:eUnderline = (FontUnderline)UNDERLINE_DOUBLEWAVE; break;
+ }
+ }
+ }
+
+ // dann Stack ggfs. verwursteln und exit!
+ if( nLen < 0 )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_UNDERLINE );
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_WORDLINEMODE );
+ }
+ else
+ {
+ NewAttr( SvxUnderlineItem( eUnderline, RES_CHRATR_UNDERLINE ));
+ if( bWordLine )
+ NewAttr(SvxWordLineModeItem(true, RES_CHRATR_WORDLINEMODE));
+ }
+}
+
+/*
+//The last three vary, measurements, rotation ? ?
+NoBracket 78 CA 06 - 02 00 00 02 34 52
+() 78 CA 06 - 02 01 00 02 34 52
+[] 78 CA 06 - 02 02 00 02 34 52
+<> 78 CA 06 - 02 03 00 02 34 52
+{} 78 CA 06 - 02 04 00 02 34 52
+*/
+void SwWW8ImplReader::Read_DoubleLine_Rotate( USHORT, const BYTE* pData,
+ short nLen )
+{
+ if( nLen < 0 ) // close the tag
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_TWO_LINES );
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ROTATE );
+ }
+ else if( pData && 6 == nLen )
+ {
+ switch( *pData )
+ {
+ case 2: // double line
+ {
+ sal_Unicode cStt = 0, cEnd = 0;
+ switch( SVBT16ToShort( pData+1 ) )
+ {
+ case 1: cStt = '(', cEnd = ')'; break;
+ case 2: cStt = '[', cEnd = ']'; break;
+ case 3: cStt = '<', cEnd = '>'; break;
+ case 4: cStt = '{', cEnd = '}'; break;
+ }
+ NewAttr( SvxTwoLinesItem( sal_True, cStt, cEnd, RES_CHRATR_TWO_LINES ));
+ }
+ break;
+
+ case 1: // rotated characters
+ {
+ bool bFitToLine = 0 != *(pData+1);
+ NewAttr( SvxCharRotateItem( 900, bFitToLine, RES_CHRATR_ROTATE ));
+ }
+ break;
+ }
+ }
+}
+
+void SwWW8ImplReader::Read_TxtColor( USHORT, const BYTE* pData, short nLen )
+{
+ //Has newer colour varient, ignore this old varient
+ if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0x6870))
+ return;
+
+ if( nLen < 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
+ else
+ {
+ BYTE b = *pData; // Parameter: 0 = Auto, 1..16 Farben
+
+ if( b > 16 ) // unbekannt -> Black
+ b = 0;
+
+ NewAttr( SvxColorItem(Color(GetCol(b)), RES_CHRATR_COLOR));
+ if (pAktColl && pStyles)
+ pStyles->bTxtColChanged = true;
+ }
+}
+
+sal_uInt32 wwUtility::BGRToRGB(sal_uInt32 nColor)
+{
+ sal_uInt8
+ r(static_cast<sal_uInt8>(nColor&0xFF)),
+ g(static_cast<sal_uInt8>(((nColor)>>8)&0xFF)),
+ b(static_cast<sal_uInt8>((nColor>>16)&0xFF)),
+ t(static_cast<sal_uInt8>((nColor>>24)&0xFF));
+ nColor = (t<<24) + (r<<16) + (g<<8) + b;
+ return nColor;
+}
+
+void SwWW8ImplReader::Read_TxtForeColor(USHORT, const BYTE* pData, short nLen)
+{
+ if( nLen < 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
+ else
+ {
+ Color aColor(wwUtility::BGRToRGB(SVBT32ToUInt32(pData)));
+ NewAttr(SvxColorItem(aColor, RES_CHRATR_COLOR));
+ if (pAktColl && pStyles)
+ pStyles->bTxtColChanged = true;
+ }
+}
+
+bool SwWW8ImplReader::GetFontParams( USHORT nFCode, FontFamily& reFamily,
+ String& rName, FontPitch& rePitch, CharSet& reCharSet )
+{
+ // Die Defines, aus denen diese Tabellen erzeugt werden, stehen in windows.h
+ static const FontPitch ePitchA[] =
+ {
+ PITCH_DONTKNOW, PITCH_FIXED, PITCH_VARIABLE, PITCH_DONTKNOW
+ };
+
+ static const FontFamily eFamilyA[] =
+ {
+ FAMILY_DONTKNOW, FAMILY_ROMAN, FAMILY_SWISS, FAMILY_MODERN,
+ FAMILY_SCRIPT, FAMILY_DECORATIVE
+ };
+
+ const WW8_FFN* pF = pFonts->GetFont( nFCode ); // Info dazu
+ if( !pF ) // FontNummer unbekannt ?
+ return false; // dann ignorieren
+
+ rName = String( pF->sFontname );
+
+ // pF->prg : Pitch
+ rePitch = ePitchA[pF->prg];
+
+ // pF->chs: Charset
+ if( 77 == pF->chs ) // Mac-Font im Mac-Charset oder
+ reCharSet = eTextCharSet; // auf ANSI-Charset uebersetzt
+ else
+ { // patch from cmc for #i52786#
+ // #i52786#, for word 67 we'll assume that ANSI is basically invalid,
+ // might be true for (above) mac as well, but would need a mac example
+ // that exercises this to be sure
+ if (bVer67 && pF->chs == 0)
+ reCharSet = RTL_TEXTENCODING_DONTKNOW;
+ else
+ reCharSet = rtl_getTextEncodingFromWindowsCharset( pF->chs );
+ }
+
+ // pF->ff : Family
+ BYTE b = pF->ff;
+
+ // make sure Font Family Code is set correctly
+ // at least for the most important fonts
+ // ( might be set wrong when Doc was not created by
+ // Winword but by third party program like Applixware... )
+ /*
+ 0: FAMILY_DONTKNOW
+ 1: FAMILY_ROMAN
+ 2: FAMILY_SWISS
+ 3: FAMILY_MODERN
+ 4: FAMILY_SCRIPT
+ 5: FAMILY_DECORATIVE
+ */
+#define FONTNAMETAB_SZ 14
+#define MAX_FONTNAME_ROMAN 6
+ static const sal_Char
+ // first comes ROMAN
+ sFontName0[] = "\x07""Tms Rmn",
+ sFontName1[] = "\x07""Timmons",
+ sFontName2[] = "\x08""CG Times",
+ sFontName3[] = "\x08""MS Serif",
+ sFontName4[] = "\x08""Garamond",
+ sFontName5[] = "\x11""Times Roman",
+ sFontName6[] = "\x15""Times New Roman",
+ // from here SWISS --> see above: #define MAX_FONTNAME_ROMAN 6
+ sFontName7[] = "\x04""Helv",
+ sFontName8[] = "\x05""Arial",
+ sFontName9[] = "\x07""Univers",
+ sFontName10[]= "\x11""LinePrinter",
+ sFontName11[]= "\x11""Lucida Sans",
+ sFontName12[]= "\x11""Small Fonts",
+ sFontName13[]= "\x13""MS Sans Serif";
+ static const sal_Char* const aFontNameTab[ FONTNAMETAB_SZ ] =
+ {
+ sFontName0, sFontName1, sFontName2, sFontName3,
+ sFontName4, sFontName5, sFontName6, sFontName7,
+ sFontName8, sFontName9, sFontName10, sFontName11,
+ sFontName12, sFontName13
+ };
+
+ for( USHORT n = 0; n < FONTNAMETAB_SZ; n++ )
+ {
+ const sal_Char* pCmp = aFontNameTab[ n ];
+ xub_StrLen nLen = *pCmp++;
+ if( rName.EqualsIgnoreCaseAscii(pCmp, 0, nLen) )
+ {
+ b = n <= MAX_FONTNAME_ROMAN ? 1 : 2;
+ break;
+ }
+ }
+ if( b < sizeof( eFamilyA ) )
+ reFamily = eFamilyA[b];
+ else
+ reFamily = FAMILY_DONTKNOW;
+
+ return true;
+}
+
+USHORT SwWW8ImplReader::CorrectResIdForCharset(CharSet nCharSet, USHORT nWhich)
+{
+ USHORT nResult = 0;
+
+ switch (nCharSet) {
+ case RTL_TEXTENCODING_MS_932:
+ nResult = RES_CHRATR_CJK_FONT;
+ break;
+
+ default:
+ nResult = nWhich;
+ break;
+ }
+
+ return nResult;
+}
+
+bool SwWW8ImplReader::SetNewFontAttr(USHORT nFCode, bool bSetEnums,
+ USHORT nWhich)
+{
+ FontFamily eFamily;
+ String aName;
+ FontPitch ePitch;
+ CharSet eSrcCharSet;
+
+ if( !GetFontParams( nFCode, eFamily, aName, ePitch, eSrcCharSet ) )
+ {
+ //If we fail (and are not doing a style) then put something into the
+ //character encodings stack anyway so that the property end that pops
+ //off the stack will keep in sync
+ if (!pAktColl && IsListOrDropcap())
+ {
+ if (nWhich == RES_CHRATR_CJK_FONT)
+ {
+ if (!maFontSrcCJKCharSets.empty())
+ {
+ eSrcCharSet = maFontSrcCJKCharSets.top();
+ }
+ else
+ {
+ eSrcCharSet = RTL_TEXTENCODING_DONTKNOW;
+ }
+
+ maFontSrcCJKCharSets.push(eSrcCharSet);
+ }
+ else
+ {
+ if (!maFontSrcCharSets.empty())
+ {
+ eSrcCharSet = maFontSrcCharSets.top();
+ }
+ else
+ {
+ eSrcCharSet = RTL_TEXTENCODING_DONTKNOW;
+ }
+
+ maFontSrcCharSets.push(eSrcCharSet);
+ }
+ }
+ return false;
+ }
+
+ CharSet eDstCharSet = eSrcCharSet;
+
+ SvxFontItem aFont( eFamily, aName, aEmptyStr, ePitch, eDstCharSet, nWhich);
+
+ nWhich = CorrectResIdForCharset(eSrcCharSet, nWhich);
+
+ if( bSetEnums )
+ {
+ if( pAktColl ) // StyleDef
+ {
+ switch(nWhich)
+ {
+ default:
+ case RES_CHRATR_FONT:
+ pCollA[nAktColl].eLTRFontSrcCharSet = eSrcCharSet;
+ break;
+ case RES_CHRATR_CTL_FONT:
+ pCollA[nAktColl].eRTLFontSrcCharSet = eSrcCharSet;
+ break;
+ case RES_CHRATR_CJK_FONT:
+ pCollA[nAktColl].eCJKFontSrcCharSet = eSrcCharSet;
+ break;
+ }
+ }
+ else if (IsListOrDropcap())
+ {
+ //Add character text encoding to stack
+ if (nWhich == RES_CHRATR_CJK_FONT)
+ maFontSrcCJKCharSets.push(eSrcCharSet);
+ else
+ maFontSrcCharSets.push(eSrcCharSet);
+ }
+ }
+
+ NewAttr( aFont ); // ...und 'reinsetzen
+
+ return true;
+}
+
+void SwWW8ImplReader::ResetCharSetVars()
+{
+ ASSERT(!maFontSrcCharSets.empty(),"no charset to remove");
+ if (!maFontSrcCharSets.empty())
+ maFontSrcCharSets.pop();
+}
+
+void SwWW8ImplReader::ResetCJKCharSetVars()
+{
+ ASSERT(!maFontSrcCJKCharSets.empty(),"no charset to remove");
+ if (!maFontSrcCJKCharSets.empty())
+ maFontSrcCJKCharSets.pop();
+}
+
+/*
+ Font ein oder ausschalten:
+*/
+void SwWW8ImplReader::Read_FontCode( USHORT nId, const BYTE* pData, short nLen )
+{
+ if (!bSymbol) // falls bSymbol, gilt der am Symbol
+ { // (siehe sprmCSymbol) gesetzte Font !
+ switch( nId )
+ {
+ // case 0x4a51: //font to bias towards all else being equal ?
+ case 113:
+ case 0x4a5E:
+ nId = RES_CHRATR_CTL_FONT;
+ break;
+ case 93:
+ case 111:
+ case 0x4a4f:
+ nId = RES_CHRATR_FONT;
+ break;
+ case 112:
+ case 0x4a50:
+ nId = RES_CHRATR_CJK_FONT;
+ break;
+ default:
+ return ;
+ }
+
+ if( nLen < 0 ) // Ende des Attributes
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
+ if (nId == RES_CHRATR_CJK_FONT)
+ ResetCJKCharSetVars();
+ else
+ ResetCharSetVars();
+ }
+ else
+ {
+ USHORT nFCode = SVBT16ToShort( pData ); // Font-Nummer
+ if (SetNewFontAttr(nFCode, true, nId) // Lies Inhalt
+ && pAktColl && pStyles ) // Style-Def ?
+ {
+ // merken zur Simulation Default-Font
+ if (RES_CHRATR_CJK_FONT == nId)
+ pStyles->bCJKFontChanged = true;
+ else if (RES_CHRATR_CTL_FONT == nId)
+ pStyles->bCTLFontChanged = true;
+ else
+ pStyles->bFontChanged = true;
+ }
+ }
+ }
+}
+
+void SwWW8ImplReader::Read_FontSize( USHORT nId, const BYTE* pData, short nLen )
+{
+ switch( nId )
+ {
+ case 74:
+ case 99:
+ case 0x4a43:
+ nId = RES_CHRATR_FONTSIZE;
+ break;
+ case 85:
+ case 116:
+ case 0x4a61:
+ nId = RES_CHRATR_CTL_FONTSIZE;
+ break;
+ default:
+ return ;
+ }
+
+ if( nLen < 0 ) // Ende des Attributes
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
+ if( RES_CHRATR_FONTSIZE == nId ) // reset additional the CJK size
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_CJK_FONTSIZE );
+ }
+ else
+ {
+ ww::WordVersion eVersion = pWwFib->GetFIBVersion();
+
+ // Font-Size in half points e.g. 10 = 1440 / ( 72 * 2 )
+ USHORT nFSize = eVersion <= ww::eWW2 ? *pData : SVBT16ToShort(pData);
+ nFSize*= 10;
+
+ SvxFontHeightItem aSz( nFSize, 100, nId );
+ NewAttr( aSz );
+ if( RES_CHRATR_FONTSIZE == nId ) // set additional the CJK size
+ {
+ aSz.SetWhich( RES_CHRATR_CJK_FONTSIZE );
+ NewAttr( aSz );
+ }
+ if (pAktColl && pStyles) // Style-Def ?
+ {
+ // merken zur Simulation Default-FontSize
+ if (nId == RES_CHRATR_CTL_FONTSIZE)
+ pStyles->bFCTLSizeChanged = true;
+ else
+ pStyles->bFSizeChanged = true;
+ }
+ }
+}
+
+
+
+void SwWW8ImplReader::Read_CharSet(USHORT , const BYTE* pData, short nLen)
+{
+ if( nLen < 0 )
+ { // Ende des Attributes
+ eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
+ return;
+ }
+ BYTE nfChsDiff = SVBT8ToByte( pData );
+
+ if( nfChsDiff )
+ eHardCharSet = rtl_getTextEncodingFromWindowsCharset( *(pData + 1) );
+ else
+ eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
+}
+
+void SwWW8ImplReader::Read_Language( USHORT nId, const BYTE* pData, short nLen )
+{
+ switch( nId )
+ {
+ case 97:
+ case 0x486D:
+ case 0x4873: //Methinks, uncertain
+ nId = RES_CHRATR_LANGUAGE;
+ break;
+ case 0x486E:
+ nId = RES_CHRATR_CJK_LANGUAGE;
+ break;
+ case 83:
+ case 114:
+ case 0x485F:
+ nId = RES_CHRATR_CTL_LANGUAGE;
+ break;
+ default:
+ return;
+ }
+
+ if( nLen < 0 ) // Ende des Attributes
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
+ else
+ {
+ USHORT nLang = SVBT16ToShort( pData ); // Language-Id
+ NewAttr(SvxLanguageItem((const LanguageType)nLang, nId));
+ }
+}
+
+/*
+ Einschalten des Zeichen-Styles:
+*/
+void SwWW8ImplReader::Read_CColl( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 ){ // Ende des Attributes
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_TXTATR_CHARFMT );
+ nCharFmt = -1;
+ return;
+ }
+ USHORT nId = SVBT16ToShort( pData ); // Style-Id (NICHT Sprm-Id!)
+
+ if( nId >= nColls || !pCollA[nId].pFmt // ungueltige Id ?
+ || pCollA[nId].bColl ) // oder Para-Style ?
+ return; // dann ignorieren
+
+ NewAttr( SwFmtCharFmt( (SwCharFmt*)pCollA[nId].pFmt ) );
+ nCharFmt = (short) nId;
+}
+
+
+/*
+ enger oder weiter als normal:
+*/
+void SwWW8ImplReader::Read_Kern( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 ){ // Ende des Attributes
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_KERNING );
+ return;
+ }
+ INT16 nKern = SVBT16ToShort( pData ); // Kerning in Twips
+ NewAttr( SvxKerningItem( nKern, RES_CHRATR_KERNING ) );
+}
+
+void SwWW8ImplReader::Read_FontKern( USHORT, const BYTE* , short nLen )
+{
+ if( nLen < 0 ) // Ende des Attributes
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_AUTOKERN );
+ else
+ NewAttr(SvxAutoKernItem(true, RES_CHRATR_AUTOKERN));
+}
+
+void SwWW8ImplReader::Read_CharShadow( USHORT, const BYTE* pData, short nLen )
+{
+ //Has newer colour varient, ignore this old varient
+ if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0xCA71))
+ return;
+
+ if( nLen <= 0 )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
+ if( bCharShdTxtCol )
+ {
+ // Zeichenfarbe auch
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
+ bCharShdTxtCol = false;
+ }
+ }
+ else
+ {
+ WW8_SHD aSHD;
+ aSHD.SetWWValue( *(SVBT16*)pData );
+ SwWW8Shade aSh( bVer67, aSHD );
+
+ NewAttr( SvxBrushItem( aSh.aColor, RES_CHRATR_BACKGROUND ));
+ }
+}
+
+void SwWW8ImplReader::Read_TxtBackColor(USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen <= 0 )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
+ if( bCharShdTxtCol )
+ {
+ // Zeichenfarbe auch
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
+ bCharShdTxtCol = false;
+ }
+ }
+ else
+ {
+ ASSERT(nLen == 10, "Len of para back colour not 10!");
+ if (nLen != 10)
+ return;
+ Color aColour(ExtractColour(pData, bVer67));
+ NewAttr(SvxBrushItem(aColour, RES_CHRATR_BACKGROUND));
+ }
+}
+
+void SwWW8ImplReader::Read_CharHighlight(USHORT, const BYTE* pData, short nLen)
+{
+ if( nLen <= 0 )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_BACKGROUND );
+ if( bCharShdTxtCol )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR ); // Zeichenfarbe auch
+ bCharShdTxtCol = false;
+ }
+ }
+ else
+ {
+ BYTE b = *pData; // Parameter: 0 = Auto, 1..16 Farben
+
+ if( b > 16 ) // unbekannt -> Black
+ b = 0; // Auto -> Black
+
+ Color aCol(GetCol(b));
+ NewAttr( SvxBrushItem( aCol , RES_CHRATR_BACKGROUND ));
+ }
+}
+
+
+/***************************************************************************
+# Absatz - Attribute
+#**************************************************************************/
+
+void SwWW8ImplReader::Read_NoLineNumb(USHORT , const BYTE* pData, short nLen)
+{
+ if( nLen < 0 ) // Ende des Attributes
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_LINENUMBER );
+ return;
+ }
+ SwFmtLineNumber aLN;
+ if (const SwFmtLineNumber* pLN
+ = (const SwFmtLineNumber*)GetFmtAttr(RES_LINENUMBER))
+ {
+ aLN.SetStartValue( pLN->GetStartValue() );
+ }
+
+ aLN.SetCountLines( pData && (0 == *pData) );
+ NewAttr( aLN );
+}
+
+// Sprm 16, 17
+void SwWW8ImplReader::Read_LR( USHORT nId, const BYTE* pData, short nLen )
+{
+ if (nLen < 0) // End of the Attributes
+ {
+ pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LR_SPACE);
+ return;
+ }
+
+ short nPara = SVBT16ToShort( pData );
+
+ SvxLRSpaceItem aLR( RES_LR_SPACE );
+ const SfxPoolItem* pLR = GetFmtAttr(RES_LR_SPACE);
+ if( pLR )
+ aLR = *(const SvxLRSpaceItem*)pLR;
+
+ /*
+ The older word sprms mean left/right, while the new ones mean before/after.
+ Writer now also works with before after, so when we see old left/right and
+ we're RTL. We swap them
+ */
+ if (IsRightToLeft())
+ {
+ switch (nId)
+ {
+ //Left becomes after;
+ case 17:
+ nId = 16;
+ break;
+ case 0x840F:
+ nId = 0x840E;
+ break;
+ //Right becomes before;
+ case 16:
+ nId = 17;
+ break;
+ case 0x840E:
+ nId = 0x840F;
+ break;
+ }
+ }
+
+ // --> OD 2010-05-06 #i103711#
+ bool bFirstLinOfstSet( false );
+ // <--
+ // --> OD 2010-05-11 #i105414#
+ bool bLeftIndentSet( false );
+ // <--
+
+ switch (nId)
+ {
+ //sprmPDxaLeft
+ case 17:
+ case 0x840F:
+ case 0x845E:
+ aLR.SetTxtLeft( nPara );
+ if (pAktColl)
+ {
+ pCollA[nAktColl].bListReleventIndentSet = true;
+ }
+ // --> OD 2010-05-11 #i105414#
+ bLeftIndentSet = true;
+ // <--
+ break;
+ //sprmPDxaLeft1
+ case 19:
+ case 0x8411:
+ case 0x8460:
+ /*
+ #94672# #99584#
+ As part of an attempt to break my spirit ww 8+ formats can contain
+ ww 7- lists. If they do and the list is part of the style, then
+ when removing the list from a paragraph of that style there
+ appears to be a bug where the hanging indent value which the list
+ set is still factored into the left indent of the paragraph. Its
+ not listed in the winword dialogs, but it is clearly there. So if
+ our style has a broken ww 7- list and we know that the list has
+ been removed then we will factor the original list applied hanging
+ into our calculation.
+ */
+ if (pPlcxMan && pCollA[nAktColl].bHasBrokenWW6List)
+ {
+ const BYTE *pIsZeroed = pPlcxMan->GetPapPLCF()->HasSprm(0x460B);
+ if (pIsZeroed && *pIsZeroed == 0)
+ {
+ const SvxLRSpaceItem &rLR =
+ ItemGet<SvxLRSpaceItem>(*(pCollA[nAktColl].pFmt),
+ RES_LR_SPACE);
+ nPara = nPara - rLR.GetTxtFirstLineOfst();
+ }
+ }
+
+ aLR.SetTxtFirstLineOfst(nPara);
+ if (pAktColl)
+ {
+ pCollA[nAktColl].bListReleventIndentSet = true;
+ }
+ // --> OD 2010-05-06 #i103711#
+ bFirstLinOfstSet = true;
+ // <--
+ break;
+ //sprmPDxaRight
+ case 16:
+ case 0x840E:
+ case 0x845D:
+ aLR.SetRight( nPara );
+ break;
+ default:
+ return;
+ }
+
+ // --> OD 2010-05-06 #i103711#
+ // --> OD 2010-05-11 #i105414#
+ NewAttr( aLR, bFirstLinOfstSet, bLeftIndentSet );
+ // <--
+}
+
+// Sprm 20
+void SwWW8ImplReader::Read_LineSpace( USHORT, const BYTE* pData, short nLen )
+{
+// Kommentear siehe Read_UL()
+ if (bStyNormal && bWWBugNormal)
+ return;
+
+ if( nLen < 0 ){
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_LINESPACING );
+ if( !( nIniFlags & WW8FL_NO_IMPLPASP ) )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
+ return;
+ }
+
+ short nSpace = SVBT16ToShort( pData );
+ ww::WordVersion eVersion = pWwFib->GetFIBVersion();
+ short nMulti = (eVersion <= ww::eWW2) ? 1 : SVBT16ToShort( pData + 2 );
+
+ SvxLineSpace eLnSpc;
+ if( 0 > nSpace )
+ {
+ nSpace = -nSpace;
+ eLnSpc = SVX_LINE_SPACE_FIX;
+ }
+ else
+ eLnSpc = SVX_LINE_SPACE_MIN;
+
+// WW hat einen impliziten zusaetzlichen Absatzabstand abhaengig vom
+// Zeilenabstand. Er betraegt bei "genau", 0.8*Zeilenabstand "vor" und
+// 0.2*Zeilenabstand "nach".
+// Bei "Mindestens" sind es 1*Zeilenabstand "vor" und 0*Zeilenabstand "nach".
+// Bei Mehrfach sind es 0 "vor" und min( 0cm, FontSize*(nFach-1) ) "nach".
+//
+// SW hat auch einen impliziten Zeilenabstand. er betraegt bei "mindestens"
+// 1*Zeilenabstand "vor" und 0 "nach"
+// bei proportional betraegt er min( 0cm, FontSize*(nFach-1) ) sowohl "vor"
+// wie auch "nach"
+
+ USHORT nWwPre = 0;
+ USHORT nWwPost = 0;
+ USHORT nSwPre = 0;
+ USHORT nSwPost = 0;
+ USHORT nSpaceTw = 0;
+
+ SvxLineSpacingItem aLSpc( LINE_SPACE_DEFAULT_HEIGHT, RES_PARATR_LINESPACING );
+
+ if( 1 == nMulti ) // MultilineSpace ( proportional )
+ {
+ long n = nSpace * 10 / 24; // WW: 240 = 100%, SW: 100 = 100%
+
+//JP 03.12.98: nach Absprache mit AMA ist die Begrenzung unsinnig
+ if( n>200 ) n = 200; // SW_UI-Maximum
+ aLSpc.SetPropLineSpace( (const BYTE)n );
+ const SvxFontHeightItem* pH = (const SvxFontHeightItem*)
+ GetFmtAttr( RES_CHRATR_FONTSIZE );
+ nSpaceTw = (USHORT)( n * pH->GetHeight() / 100 );
+
+ if( n > 100 )
+ nWwPost = nSwPre = nSwPost = (USHORT)( ( n - 100 )
+ * pH->GetHeight() / 100 );
+ }
+ else // Fixed / Minimum
+ {
+ // bei negativen Space ist der Abstand exakt, sonst minimum
+ nSpaceTw = (USHORT)nSpace;
+ aLSpc.SetLineHeight( nSpaceTw );
+ aLSpc.GetLineSpaceRule() = eLnSpc;
+ nSwPre = nSpace;
+
+ if( SVX_LINE_SPACE_FIX == eLnSpc ) // Genau
+ {
+ nWwPre = (USHORT)( 8L * nSpace / 10 );
+ nWwPost = (USHORT)( 2L * nSpace / 10 );
+ nSwPre = nSpace;
+ }
+ else // Minimum
+ {
+ nWwPre = (USHORT)( 129L * nSpace / 100 - 95 );// erst bei groesseren
+ // Zeilenabstaenden
+ }
+ }
+ NewAttr( aLSpc );
+ if( pSFlyPara )
+ pSFlyPara->nLineSpace = nSpaceTw; // LineSpace fuer Graf-Apos
+}
+
+//#i18519# AutoSpace value depends on Dop fDontUseHTMLAutoSpacing setting
+sal_uInt16 SwWW8ImplReader::GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing)
+{
+ if (fDontUseHTMLAutoSpacing)
+ return 100; //Seems to be always 5points in this case
+ else
+ return 280; //Seems to be always 14points in this case
+}
+
+void SwWW8ImplReader::Read_DontAddEqual(USHORT, const BYTE *pData, short nLen)
+{
+ if (nLen < 0)
+ return;
+
+ if (*pData)
+ maTracer.Log(sw::log::eDontAddSpaceForEqualStyles);
+}
+
+void SwWW8ImplReader::Read_ParaAutoBefore(USHORT, const BYTE *pData, short nLen)
+{
+ if (nLen < 0)
+ {
+ pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_UL_SPACE);
+ return;
+ }
+
+ if (*pData)
+ {
+ SvxULSpaceItem aUL(*(const SvxULSpaceItem*)GetFmtAttr(RES_UL_SPACE));
+ aUL.SetUpper(GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
+ NewAttr(aUL);
+ if (pAktColl)
+ pCollA[nAktColl].bParaAutoBefore = true;
+ else
+ bParaAutoBefore = true;
+ }
+ else
+ {
+ if (pAktColl)
+ pCollA[nAktColl].bParaAutoBefore = false;
+ else
+ bParaAutoBefore = false;
+ }
+}
+
+void SwWW8ImplReader::Read_ParaAutoAfter(USHORT, const BYTE *pData, short nLen)
+{
+ if (nLen < 0)
+ {
+ pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_UL_SPACE);
+ return;
+ }
+
+ if (*pData)
+ {
+ SvxULSpaceItem aUL(*(const SvxULSpaceItem*)GetFmtAttr(RES_UL_SPACE));
+ aUL.SetLower(GetParagraphAutoSpace(pWDop->fDontUseHTMLAutoSpacing));
+ NewAttr(aUL);
+ if (pAktColl)
+ pCollA[nAktColl].bParaAutoAfter = true;
+ else
+ bParaAutoAfter = true;
+ }
+ else
+ {
+ if (pAktColl)
+ pCollA[nAktColl].bParaAutoAfter = false;
+ else
+ bParaAutoAfter = false;
+ }
+}
+
+// Sprm 21, 22
+void SwWW8ImplReader::Read_UL( USHORT nId, const BYTE* pData, short nLen )
+{
+// Nun eine Umpopelung eines WW-Fehlers: Bei nProduct == 0c03d wird
+// faelschlicherweise ein DyaAfter 240 ( delta y abstand after, amn.d.?b.)
+// im Style "Normal" eingefuegt, der
+// gar nicht da ist. Ueber das IniFlag WW8FL_NO_STY_DYA laesst sich dieses
+// Verhalten auch fuer andere WW-Versionen erzwingen
+// ASSERT( !bStyNormal || bWWBugNormal, "+Dieses Doc deutet evtl. auf einen
+// Fehler in der benutzten WW-Version hin. Wenn sich die Styles <Standard> bzw.
+// <Normal> zwischen WW und SW im Absatz- oder Zeilenabstand unterscheiden,
+// dann bitte dieses Doc SH zukommen lassen." );
+// bWWBugNormal ist kein hinreichendes Kriterium dafuer, dass der
+// angegebene Abstand falsch ist
+
+ if( nLen < 0 )
+ {
+ // Ende des Attributes
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_UL_SPACE );
+ return;
+ }
+ short nPara = SVBT16ToShort( pData );
+ if( nPara < 0 )
+ nPara = -nPara;
+
+ SvxULSpaceItem aUL( *(const SvxULSpaceItem*)GetFmtAttr( RES_UL_SPACE ));
+
+ switch( nId )
+ {
+ //sprmPDyaBefore
+ case 21:
+ case 0xA413:
+ aUL.SetUpper( nPara );
+ break;
+ //sprmPDyaAfter
+ case 22:
+ case 0xA414:
+ aUL.SetLower( nPara );
+ break;
+ default:
+ return;
+ };
+
+ NewAttr( aUL );
+}
+
+void SwWW8ImplReader::Read_IdctHint( USHORT, const BYTE* pData, short nLen )
+{
+ if (nLen < 0)
+ nIdctHint = 0;
+ else
+ nIdctHint = *pData;
+}
+
+void SwWW8ImplReader::Read_Justify( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ADJUST );
+ return;
+ }
+
+ SvxAdjust eAdjust(SVX_ADJUST_LEFT);
+ bool bDistributed = false;
+ switch (*pData)
+ {
+ default:
+ case 0:
+ break;
+ case 1:
+ eAdjust = SVX_ADJUST_CENTER;
+ break;
+ case 2:
+ eAdjust = SVX_ADJUST_RIGHT;
+ break;
+ case 3:
+ eAdjust = SVX_ADJUST_BLOCK;
+ break;
+ case 4:
+ eAdjust = SVX_ADJUST_BLOCK;
+ bDistributed = true;
+ break;
+ }
+ SvxAdjustItem aAdjust(eAdjust, RES_PARATR_ADJUST);
+ if (bDistributed)
+ aAdjust.SetLastBlock(SVX_ADJUST_BLOCK);
+
+ NewAttr(aAdjust);
+}
+
+bool SwWW8ImplReader::IsRightToLeft()
+{
+ bool bRTL = false;
+ const BYTE *pDir =
+ pPlcxMan ? pPlcxMan->GetPapPLCF()->HasSprm(0x2441) : 0;
+ if (pDir)
+ bRTL = *pDir ? true : false;
+ else
+ {
+ const SvxFrameDirectionItem* pItem=
+ (const SvxFrameDirectionItem*)GetFmtAttr(RES_FRAMEDIR);
+ if (pItem && (pItem->GetValue() == FRMDIR_HORI_RIGHT_TOP))
+ bRTL = true;
+ }
+ return bRTL;
+}
+
+void SwWW8ImplReader::Read_RTLJustify( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ADJUST );
+ return;
+ }
+
+ //If we are in a ltr paragraph this is the same as normal Justify,
+ //If we are in a rtl paragraph the meaning is reversed.
+ if (!IsRightToLeft())
+ Read_Justify(0x2403 /*dummy*/, pData, nLen);
+ else
+ {
+ SvxAdjust eAdjust(SVX_ADJUST_RIGHT);
+ bool bDistributed = false;
+ switch (*pData)
+ {
+ default:
+ case 0:
+ break;
+ case 1:
+ eAdjust = SVX_ADJUST_CENTER;
+ break;
+ case 2:
+ eAdjust = SVX_ADJUST_LEFT;
+ break;
+ case 3:
+ eAdjust = SVX_ADJUST_BLOCK;
+ break;
+ case 4:
+ eAdjust = SVX_ADJUST_BLOCK;
+ bDistributed = true;
+ break;
+ }
+ SvxAdjustItem aAdjust(eAdjust, RES_PARATR_ADJUST);
+ if (bDistributed)
+ aAdjust.SetLastBlock(SVX_ADJUST_BLOCK);
+
+ NewAttr(aAdjust);
+ }
+}
+
+void SwWW8ImplReader::Read_BoolItem( USHORT nId, const BYTE* pData, short nLen )
+{
+ switch( nId )
+ {
+ case 0x2433:
+ nId = RES_PARATR_FORBIDDEN_RULES;
+ break;
+ case 0x2435:
+ nId = RES_PARATR_HANGINGPUNCTUATION;
+ break;
+ case 0x2437:
+ nId = RES_PARATR_SCRIPTSPACE;
+ break;
+ default:
+ ASSERT( !this, "wrong Id" );
+ return ;
+ }
+
+ if( nLen < 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), nId );
+ else
+ {
+ SfxBoolItem* pI = (SfxBoolItem*)GetDfltAttr( nId )->Clone();
+ pI->SetValue( 0 != *pData );
+ NewAttr( *pI );
+ delete pI;
+ }
+}
+
+void SwWW8ImplReader::Read_Emphasis( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_EMPHASIS_MARK );
+ else
+ {
+ LanguageType nLang;
+ //Check to see if there is an up and coming cjk language property. If
+ //there is use it, if there is not fall back to the currently set one.
+ //Only the cjk language setting seems to matter to word, the western
+ //one is ignored
+ const BYTE *pLang =
+ pPlcxMan ? pPlcxMan->GetChpPLCF()->HasSprm(0x486E) : 0;
+
+ if (pLang)
+ nLang = SVBT16ToShort( pLang );
+ else
+ {
+ nLang = ((const SvxLanguageItem *)
+ GetFmtAttr(RES_CHRATR_CJK_LANGUAGE))->GetLanguage();
+ }
+
+ sal_uInt16 nVal;
+ switch( *pData )
+ {
+ case 0:
+ nVal = EMPHASISMARK_NONE;
+ break;
+ case 2:
+ if ((nLang == LANGUAGE_CHINESE_HONGKONG) ||
+ (nLang == LANGUAGE_CHINESE_MACAU) ||
+ (nLang == LANGUAGE_CHINESE_TRADITIONAL) ||
+ (nLang == LANGUAGE_KOREAN))
+ nVal = EMPHASISMARK_CIRCLE_ABOVE;
+ else if (nLang == LANGUAGE_JAPANESE)
+ nVal = EMPHASISMARK_SIDE_DOTS;
+ else
+ nVal = EMPHASISMARK_DOTS_BELOW;
+ break;
+ case 3:
+ nVal = EMPHASISMARK_CIRCLE_ABOVE;
+ break;
+ case 4:
+ nVal = EMPHASISMARK_DOTS_BELOW;
+ break;
+ case 1:
+ if ((nLang == LANGUAGE_CHINESE_SIMPLIFIED) ||
+ (nLang == LANGUAGE_CHINESE_SINGAPORE))
+ nVal = EMPHASISMARK_DOTS_BELOW;
+ else
+ nVal = EMPHASISMARK_DOTS_ABOVE;
+ break;
+ default:
+ nVal = EMPHASISMARK_DOTS_ABOVE;
+ break;
+ }
+
+ NewAttr( SvxEmphasisMarkItem( nVal, RES_CHRATR_EMPHASIS_MARK ) );
+ }
+}
+
+void SwWW8ImplReader::Read_ScaleWidth( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_SCALEW );
+ else
+ {
+ sal_uInt16 nVal = SVBT16ToShort( pData );
+ //The number must be between 1 and 600
+ if (nVal < 1 || nVal > 600)
+ nVal = 100;
+ NewAttr( SvxCharScaleWidthItem( nVal, RES_CHRATR_SCALEW ) );
+ }
+}
+
+void SwWW8ImplReader::Read_Relief( USHORT nId, const BYTE* pData, short nLen )
+{
+ if( nLen < 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_RELIEF );
+ else
+ {
+ if( *pData )
+ {
+// JP 16.03.2001 - not so eays because this is also a toggle attribute!
+// 2 x emboss on -> no emboss !!!
+// the actual value must be searched over the stack / template
+
+ const SvxCharReliefItem* pOld = (const SvxCharReliefItem*)
+ GetFmtAttr( RES_CHRATR_RELIEF );
+ FontRelief nNewValue = 0x854 == nId ? RELIEF_ENGRAVED
+ : ( 0x858 == nId ? RELIEF_EMBOSSED
+ : RELIEF_NONE );
+ if( pOld->GetValue() == nNewValue )
+ {
+ if( RELIEF_NONE != nNewValue )
+ nNewValue = RELIEF_NONE;
+ }
+ NewAttr( SvxCharReliefItem( nNewValue, RES_CHRATR_RELIEF ));
+ }
+ }
+}
+
+void SwWW8ImplReader::Read_TxtAnim(USHORT /*nId*/, const BYTE* pData, short nLen)
+{
+ if (nLen < 0)
+ pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_CHRATR_BLINK);
+ else
+ {
+ if (*pData)
+ {
+ bool bBlink;
+
+ // #110851# The 7 animated text effects available in word all get
+ // mapped to a blinking text effect in StarOffice
+ // 0 no animation 1 Las Vegas lights
+ // 2 background blink 3 sparkle text
+ // 4 marching ants 5 marchine red ants
+ // 6 shimmer
+ if (*pData > 0 && *pData < 7 )
+ bBlink = true;
+ else
+ bBlink = false;
+
+ NewAttr(SvxBlinkItem(bBlink, RES_CHRATR_BLINK));
+ }
+ }
+}
+
+SwWW8Shade::SwWW8Shade(bool bVer67, const WW8_SHD& rSHD)
+{
+ BYTE b = rSHD.GetFore();
+ ASSERT(b < 17, "ww8: colour out of range");
+ if (b >= 17)
+ b = 0;
+
+ ColorData nFore(SwWW8ImplReader::GetCol(b));
+
+ b = rSHD.GetBack();
+ ASSERT(b < 17, "ww8: colour out of range");
+ if( b >= 17 )
+ b = 0;
+
+ ColorData nBack(SwWW8ImplReader::GetCol(b));
+
+ b = rSHD.GetStyle(bVer67);
+
+ SetShade(nFore, nBack, b);
+}
+
+void SwWW8Shade::SetShade(ColorData nFore, ColorData nBack, sal_uInt16 nIndex)
+{
+ static const ULONG eMSGrayScale[] =
+ {
+ // Nul-Brush
+ 0, // 0
+ // Solid-Brush
+ 1000, // 1
+ // promillemaessig abgestufte Schattierungen
+ 50, // 2
+ 100, // 3
+ 200, // 4
+ 250, // 5
+ 300, // 6
+ 400, // 7
+ 500, // 8
+ 600, // 9
+ 700, // 10
+ 750, // 11
+ 800, // 12
+ 900, // 13
+ 333, // 14 Dark Horizontal
+ 333, // 15 Dark Vertical
+ 333, // 16 Dark Forward Diagonal
+ 333, // 17 Dark Backward Diagonal
+ 333, // 18 Dark Cross
+ 333, // 19 Dark Diagonal Cross
+ 333, // 20 Horizontal
+ 333, // 21 Vertical
+ 333, // 22 Forward Diagonal
+ 333, // 23 Backward Diagonal
+ 333, // 24 Cross
+ 333, // 25 Diagonal Cross
+ // neun Nummern ohne Bedeutung in Ver8
+ 500, // 26
+ 500, // 27
+ 500, // 28
+ 500, // 29
+ 500, // 30
+ 500, // 31
+ 500, // 32
+ 500, // 33
+ 500, // 34
+ // und weiter gehts mit tollen Schattierungen ;-)
+ 25, // 35
+ 75, // 36
+ 125, // 37
+ 150, // 38
+ 175, // 39
+ 225, // 40
+ 275, // 41
+ 325, // 42
+ 350, // 43
+ 375, // 44
+ 425, // 45
+ 450, // 46
+ 475, // 47
+ 525, // 48
+ 550, // 49
+ 575, // 50
+ 625, // 51
+ 650, // 52
+ 675, // 53
+ 725, // 54
+ 775, // 55
+ 825, // 56
+ 850, // 57
+ 875, // 58
+ 925, // 59
+ 950, // 60
+ 975, // 61
+ // und zu guter Letzt:
+ 970
+ };// 62
+
+
+ //NO auto for shading so Foreground: Auto = Black
+ if (nFore == COL_AUTO)
+ nFore = COL_BLACK;
+
+ //NO auto for shading so background: Auto = Weiss
+ ColorData nUseBack = nBack;
+ if (nUseBack == COL_AUTO)
+ nUseBack = COL_WHITE;
+
+
+ if( nIndex >= sizeof( eMSGrayScale ) / sizeof ( eMSGrayScale[ 0 ] ) )
+ nIndex = 0;
+
+ ULONG nWW8BrushStyle = eMSGrayScale[nIndex];
+
+ switch (nWW8BrushStyle)
+ {
+ case 0: // Null-Brush
+ aColor.SetColor( nBack );
+ break;
+ default:
+ {
+ Color aForeColor(nFore);
+ Color aBackColor(nUseBack);
+
+ sal_uInt32 nRed = aForeColor.GetRed() * nWW8BrushStyle;
+ sal_uInt32 nGreen = aForeColor.GetGreen() * nWW8BrushStyle;
+ sal_uInt32 nBlue = aForeColor.GetBlue() * nWW8BrushStyle;
+ nRed += aBackColor.GetRed() * (1000L - nWW8BrushStyle);
+ nGreen += aBackColor.GetGreen()* (1000L - nWW8BrushStyle);
+ nBlue += aBackColor.GetBlue() * (1000L - nWW8BrushStyle);
+
+ aColor.SetColor( RGB_COLORDATA( nRed/1000, nGreen/1000,
+ nBlue/1000 ) );
+ }
+ break;
+ }
+}
+
+void SwWW8ImplReader::Read_Shade( USHORT, const BYTE* pData, short nLen )
+{
+ if (!bVer67 && pPlcxMan && pPlcxMan->GetPapPLCF()->HasSprm(0xC64D))
+ return;
+
+ if (nLen <= 0)
+ {
+ // Ende des Attributes
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BACKGROUND );
+ if (bShdTxtCol)
+ {
+ // Zeichenfarbe auch
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
+ bShdTxtCol = false;
+ }
+ }
+ else
+ {
+ WW8_SHD aSHD;
+ aSHD.SetWWValue( *(SVBT16*)pData );
+ SwWW8Shade aSh( bVer67, aSHD );
+
+ NewAttr(SvxBrushItem(aSh.aColor, RES_BACKGROUND));
+ }
+}
+
+void SwWW8ImplReader::Read_ParaBackColor(USHORT, const BYTE* pData, short nLen)
+{
+ if (nLen <= 0)
+ {
+ // Ende des Attributes
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BACKGROUND );
+ if (bShdTxtCol)
+ {
+ // Zeichenfarbe auch
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_COLOR );
+ bShdTxtCol = false;
+ }
+ }
+ else
+ {
+ ASSERT(nLen == 10, "Len of para back colour not 10!");
+ if (nLen != 10)
+ return;
+ NewAttr(SvxBrushItem(Color(ExtractColour(pData, bVer67)), RES_BACKGROUND));
+ }
+}
+
+sal_uInt32 SwWW8ImplReader::ExtractColour(const BYTE* &rpData,
+ bool
+#ifdef DBG_UTIL
+ bVer67
+#endif
+ )
+{
+ ASSERT(bVer67 == false, "Impossible");
+ //ASSERT(SVBT32ToUInt32(rpData) == 0xFF000000, "Unknown 1 not 0xff000000");
+ sal_uInt32 nFore = wwUtility::BGRToRGB(SVBT32ToUInt32(rpData));
+ rpData+=4;
+ sal_uInt32 nBack = wwUtility::BGRToRGB(SVBT32ToUInt32(rpData));
+ rpData+=4;
+ sal_uInt16 nIndex = SVBT16ToShort(rpData);
+ rpData+=2;
+ //Being a transparent background colour doesn't actually show the page
+ //background through, it merely acts like white
+ if (nBack == 0xFF000000)
+ nBack = COL_AUTO;
+ ASSERT(nBack == COL_AUTO || !(nBack & 0xFF000000),
+ "ww8: don't know what to do with such a transparent bg colour, report");
+ SwWW8Shade aShade(nFore, nBack, nIndex);
+ return aShade.aColor.GetColor();
+}
+
+void SwWW8ImplReader::Read_Border(USHORT , const BYTE* , short nLen)
+{
+ if( nLen < 0 )
+ {
+ if( bHasBorder )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BOX );
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_SHADOW );
+ bHasBorder = false;
+ }
+ }
+ else if( !bHasBorder )
+ {
+ // die Borders auf allen 4 Seiten werden gebuendelt. dieses
+ // vereinfacht die Verwaltung, d.h. die Box muss nicht 4 mal auf den
+ // CtrlStack und wieder runter
+ bHasBorder = true;
+
+ WW8_BRC5 aBrcs; // Top, Left, Bottom, Right, Between
+ BYTE nBorder;
+
+ if( pAktColl )
+ nBorder = ::lcl_ReadBorders(bVer67, aBrcs, 0, pStyles);
+ else
+ nBorder = ::lcl_ReadBorders(bVer67, aBrcs, pPlcxMan->GetPapPLCF());
+
+ if( nBorder ) // Border
+ {
+ bool bIsB = IsBorder(aBrcs, true);
+ if (!InLocalApo() || !bIsB ||
+ (pWFlyPara && !pWFlyPara->bBorderLines ))
+ {
+ // in Apo keine Umrandungen *ein*-schalten, da ich
+ // sonst die Flyumrandungen doppelt bekomme
+ // JP 04.12.98: aber nur wenn am Fly ein gesetzt ist, keine
+ // uebernehmen. Sonst wird gar keine gesetzt!
+ // Bug #59619#
+
+ // auch wenn kein Rand gesetzt ist, muss das Attribut gesetzt
+ // werden, sonst ist kein hartes Ausschalten von Style-Attrs
+ // moeglich
+ const SvxBoxItem* pBox
+ = (const SvxBoxItem*)GetFmtAttr( RES_BOX );
+ SvxBoxItem aBox(RES_BOX);
+ if (pBox)
+ aBox = *pBox;
+ short aSizeArray[5]={0};
+
+ SetBorder(aBox, aBrcs, &aSizeArray[0], nBorder);
+
+ Rectangle aInnerDist;
+ GetBorderDistance( aBrcs, aInnerDist );
+
+ maTracer.Log(sw::log::eBorderDistOutside);
+
+ aBox.SetDistance( (USHORT)aInnerDist.Left(), BOX_LINE_LEFT );
+ aBox.SetDistance( (USHORT)aInnerDist.Top(), BOX_LINE_TOP );
+ aBox.SetDistance( (USHORT)aInnerDist.Right(), BOX_LINE_RIGHT );
+ aBox.SetDistance( (USHORT)aInnerDist.Bottom(), BOX_LINE_BOTTOM );
+
+ NewAttr( aBox );
+
+ SvxShadowItem aS(RES_SHADOW);
+ if( SetShadow( aS, &aSizeArray[0], aBrcs ) )
+ NewAttr( aS );
+ }
+ }
+ }
+}
+
+void SwWW8ImplReader::Read_Hyphenation( USHORT, const BYTE* pData, short nLen )
+{
+ // set Hyphenation flag
+ if( nLen <= 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_HYPHENZONE );
+ else
+ {
+ SvxHyphenZoneItem aAttr(
+ *(const SvxHyphenZoneItem*)GetFmtAttr( RES_PARATR_HYPHENZONE ) );
+
+ aAttr.SetHyphen( 0 == *pData ); // sic !
+
+ if( !*pData )
+ {
+ aAttr.GetMinLead() = 2;
+ aAttr.GetMinTrail() = 2;
+ aAttr.GetMaxHyphens() = 0;
+ }
+
+ NewAttr( aAttr );
+ }
+}
+
+void SwWW8ImplReader::Read_WidowControl( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen <= 0 )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_WIDOWS );
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ORPHANS );
+ }
+ else
+ {
+ BYTE nL = ( *pData & 1 ) ? 2 : 0;
+
+ NewAttr( SvxWidowsItem( nL, RES_PARATR_WIDOWS ) ); // Aus -> nLines = 0
+ NewAttr( SvxOrphansItem( nL, RES_PARATR_ORPHANS ) );
+
+ if( pAktColl && pStyles ) // Style-Def ?
+ pStyles->bWidowsChanged = true; // merken zur Simulation
+ // Default-Widows
+ }
+}
+
+void SwWW8ImplReader::Read_UsePgsuSettings(USHORT,const BYTE* pData,short nLen)
+{
+ if( nLen <= 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_SNAPTOGRID);
+ else
+ {
+ if(nInTable)
+ NewAttr( SvxParaGridItem(false, RES_PARATR_SNAPTOGRID) );
+ else
+ NewAttr( SvxParaGridItem(*pData, RES_PARATR_SNAPTOGRID) );
+ }
+}
+
+void SwWW8ImplReader::Read_AlignFont( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen <= 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_VERTALIGN);
+ else
+ {
+ sal_uInt16 nVal = SVBT16ToShort( pData );
+ switch (nVal)
+ {
+ case 0:
+ nVal = SvxParaVertAlignItem::TOP;
+ break;
+ case 1:
+ nVal = SvxParaVertAlignItem::CENTER;
+ break;
+ case 2:
+ nVal = SvxParaVertAlignItem::BASELINE;
+ break;
+ case 3:
+ nVal = SvxParaVertAlignItem::BOTTOM;
+ break;
+ case 4:
+ nVal = SvxParaVertAlignItem::AUTOMATIC;
+ break;
+ default:
+ nVal = SvxParaVertAlignItem::AUTOMATIC;
+ ASSERT(!this,"Unknown paragraph vertical align");
+ break;
+ }
+ NewAttr( SvxParaVertAlignItem( nVal, RES_PARATR_VERTALIGN ) );
+ }
+}
+
+void SwWW8ImplReader::Read_KeepLines( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen <= 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_SPLIT );
+ else
+ NewAttr( SvxFmtSplitItem( ( *pData & 1 ) == 0, RES_PARATR_SPLIT ) );
+}
+
+void SwWW8ImplReader::Read_KeepParas( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen <= 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_KEEP );
+ else
+ NewAttr( SvxFmtKeepItem( ( *pData & 1 ) != 0 , RES_KEEP) );
+}
+
+void SwWW8ImplReader::Read_BreakBefore( USHORT, const BYTE* pData, short nLen )
+{
+ if( nLen <= 0 )
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_BREAK );
+ else
+ NewAttr( SvxFmtBreakItem(
+ ( *pData & 1 ) ? SVX_BREAK_PAGE_BEFORE : SVX_BREAK_NONE, RES_BREAK ) );
+}
+
+void SwWW8ImplReader::Read_ApoPPC( USHORT, const BYTE* pData, short )
+{
+ if (pAktColl) // only for Styledef, sonst anders geloest
+ {
+ SwWW8StyInf& rSI = pCollA[nAktColl];
+ WW8FlyPara* pFly = rSI.pWWFly ? rSI.pWWFly : new WW8FlyPara(bVer67);
+ pCollA[nAktColl].pWWFly = pFly;
+ pFly->Read(pData, pStyles);
+ if (pFly->IsEmpty())
+ delete pCollA[nAktColl].pWWFly, pCollA[nAktColl].pWWFly = 0;
+ }
+}
+
+bool SwWW8ImplReader::ParseTabPos(WW8_TablePos *pTabPos, WW8PLCFx_Cp_FKP* pPap)
+{
+ bool bRet = false;
+ const BYTE *pRes=0;
+ memset(pTabPos, 0, sizeof(WW8_TablePos));
+ if (0 != (pRes = pPap->HasSprm(0x360D)))
+ {
+ pTabPos->nSp29 = *pRes;
+ pTabPos->nSp37 = 2; //Possible fail area, always parallel wrap
+ if (0 != (pRes = pPap->HasSprm(0x940E)))
+ pTabPos->nSp26 = SVBT16ToShort(pRes);
+ if (0 != (pRes = pPap->HasSprm(0x940F)))
+ pTabPos->nSp27 = SVBT16ToShort(pRes);
+ if (0 != (pRes = pPap->HasSprm(0x9410)))
+ pTabPos->nLeMgn = SVBT16ToShort(pRes);
+ if (0 != (pRes = pPap->HasSprm(0x941E)))
+ pTabPos->nRiMgn = SVBT16ToShort(pRes);
+ if (0 != (pRes = pPap->HasSprm(0x9411)))
+ pTabPos->nUpMgn = SVBT16ToShort(pRes);
+ if (0 != (pRes = pPap->HasSprm(0x941F)))
+ pTabPos->nLoMgn = SVBT16ToShort(pRes);
+ bRet = true;
+ }
+ return bRet;
+}
+
+/***************************************************************************
+# Seiten - Attribute werden nicht mehr als Attribute gehandhabt
+# ( ausser OLST )
+#**************************************************************************/
+
+
+long SwWW8ImplReader::ImportExtSprm(WW8PLCFManResult* pRes)
+{
+ /*************************************************************************
+ # Arrays zum Lesen der erweiterten ( selbstdefinierten ) SPRMs
+ #*************************************************************************/
+ typedef long (SwWW8ImplReader:: *FNReadRecordExt)(WW8PLCFManResult*);
+
+ static const FNReadRecordExt aWwSprmTab[] =
+ {
+ /* 0 (256) */ &SwWW8ImplReader::Read_Ftn, // FootNote
+ /* 1 (257) */ &SwWW8ImplReader::Read_Ftn, // EndNote
+ /* 2 (258) */ &SwWW8ImplReader::Read_Field, // Feld
+ /* 3 (259) */ &SwWW8ImplReader::Read_Book, // Bookmark
+ /* 4 (260) */ &SwWW8ImplReader::Read_And // Annotation
+ };
+
+ if( pRes->nSprmId < 280 )
+ {
+ BYTE nIdx = static_cast< BYTE >(pRes->nSprmId - eFTN);
+ if( nIdx < sizeof( aWwSprmTab ) / sizeof( *aWwSprmTab )
+ && aWwSprmTab[nIdx] )
+ return (this->*aWwSprmTab[nIdx])(pRes);
+ else
+ return 0;
+ }
+ else
+ return 0;
+}
+
+void SwWW8ImplReader::EndExtSprm(USHORT nSprmId)
+{
+ typedef sal_uInt16 (SwWW8ImplReader:: *FNReadRecordExt)();
+
+ static const FNReadRecordExt aWwSprmTab[] =
+ {
+ /* 0 (256) */ &SwWW8ImplReader::End_Ftn, // FootNote
+ /* 1 (257) */ &SwWW8ImplReader::End_Ftn, // EndNote
+ /* 2 (258) */ &SwWW8ImplReader::End_Field, // Feld
+ /* 3 (259) */ 0, // Bookmark
+ /* 4 (260) */ 0 // Annotation
+ };
+
+ BYTE nIdx = static_cast< BYTE >(nSprmId - eFTN);
+ if( nIdx < sizeof( aWwSprmTab ) / sizeof( *aWwSprmTab )
+ && aWwSprmTab[nIdx] )
+ (this->*aWwSprmTab[nIdx])();
+}
+
+/***************************************************************************
+# Arrays zum Lesen der SPRMs
+#**************************************************************************/
+
+// Funktion zum Einlesen von Sprms. Par1: SprmId
+typedef void (SwWW8ImplReader:: *FNReadRecord)( USHORT, const BYTE*, short );
+
+struct SprmReadInfo
+{
+ USHORT nId;
+ FNReadRecord pReadFnc;
+};
+
+bool operator==(const SprmReadInfo &rFirst, const SprmReadInfo &rSecond)
+{
+ return (rFirst.nId == rSecond.nId);
+}
+
+bool operator<(const SprmReadInfo &rFirst, const SprmReadInfo &rSecond)
+{
+ return (rFirst.nId < rSecond.nId);
+}
+
+typedef ww::SortedArray<SprmReadInfo> wwSprmDispatcher;
+
+const wwSprmDispatcher *GetWW2SprmDispatcher()
+{
+ static SprmReadInfo aSprms[] =
+ {
+ {0, 0}, // "0" Default bzw. Error
+ //wird uebersprungen! ,
+ {2, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd", pap.istd
+ //(style code)
+ {3, 0}, //"sprmPIstdPermute", pap.istd
+ //permutation
+ {4, 0}, //"sprmPIncLv1",
+ //pap.istddifference
+ {5, &SwWW8ImplReader::Read_Justify}, //"sprmPJc", pap.jc
+ //(justification)
+ {6, 0}, //"sprmPFSideBySide",
+ //pap.fSideBySide
+ {7, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep", pap.fKeep
+ {8, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow ",
+ //pap.fKeepFollow
+ {9, &SwWW8ImplReader::Read_BreakBefore}, //"sprmPPageBreakBefore",
+ //pap.fPageBreakBefore
+ {10, 0}, //"sprmPBrcl", pap.brcl
+ {11, 0}, //"sprmPBrcp ", pap.brcp
+ {12, &SwWW8ImplReader::Read_ANLevelDesc}, //"sprmPAnld", pap.anld (ANLD
+ //structure)
+ {13, &SwWW8ImplReader::Read_ANLevelNo}, //"sprmPNLvlAnm", pap.nLvlAnm
+ //nn
+ {14, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb", ap.fNoLnn
+ {15, &SwWW8ImplReader::Read_Tab}, //"?sprmPChgTabsPapx",
+ //pap.itbdMac, ...
+ {16, &SwWW8ImplReader::Read_LR}, //"sprmPDxaRight", pap.dxaRight
+ {17, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft", pap.dxaLeft
+ {18, 0}, //"sprmPNest", pap.dxaLeft
+ {19, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft1", pap.dxaLeft1
+ {20, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine", pap.lspd
+ //an LSPD
+ {21, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore",
+ //pap.dyaBefore
+ {22, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter", pap.dyaAfter
+ {23, 0}, //"?sprmPChgTabs", pap.itbdMac,
+ //pap.rgdxaTab, ...
+ {24, 0}, //"sprmPFInTable", pap.fInTable
+ {25, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPTtp", pap.fTtp
+ {26, 0}, //"sprmPDxaAbs", pap.dxaAbs
+ {27, 0}, //"sprmPDyaAbs", pap.dyaAbs
+ {28, 0}, //"sprmPDxaWidth", pap.dxaWidth
+ {29, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc", pap.pcHorz,
+ //pap.pcVert
+ {30, 0}, //"sprmPBrcTop10", pap.brcTop
+ //BRC10
+ {31, 0}, //"sprmPBrcLeft10",
+ //pap.brcLeft BRC10
+ {32, 0}, //"sprmPBrcBottom10",
+ //pap.brcBottom BRC10
+ {33, 0}, //"sprmPBrcRight10",
+ //pap.brcRight BRC10
+ {34, 0}, //"sprmPBrcBetween10",
+ //pap.brcBetween BRC10
+ {35, 0}, //"sprmPBrcBar10", pap.brcBar
+ //BRC10
+ {36, 0}, //"sprmPFromText10",
+ //pap.dxaFromText dxa
+ {37, 0}, //"sprmPWr", pap.wr wr
+ {38, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop", pap.brcTop BRC
+ {39, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft",
+ //pap.brcLeft BRC
+ {40, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom",
+ //pap.brcBottom BRC
+ {41, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight",
+ //pap.brcRight BRC
+ {42, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween",
+ //pap.brcBetween BRC
+ {43, 0}, //"sprmPBrcBar", pap.brcBar
+ //BRC word
+ {44, &SwWW8ImplReader::Read_Hyphenation}, //"sprmPFNoAutoHyph",
+ //pap.fNoAutoHyph
+ {45, 0}, //"sprmPWHeightAbs",
+ //pap.wHeightAbs w
+ {46, 0}, //"sprmPDcs", pap.dcs DCS
+ {47, &SwWW8ImplReader::Read_Shade}, //"sprmPShd", pap.shd SHD
+ {48, 0}, //"sprmPDyaFromText",
+ //pap.dyaFromText dya
+ {49, 0}, //"sprmPDxaFromText",
+ //pap.dxaFromText dxa
+ {50, 0}, //"sprmPFLocked", pap.fLocked
+ //0 or 1 byte
+ {51, &SwWW8ImplReader::Read_WidowControl}, //"sprmPFWidowControl",
+ //pap.fWidowControl 0 or 1 byte
+ {52, 0}, //"?sprmPRuler 52",
+ {53, 0}, //"??53",
+ {54, 0}, //"??54",
+ {55, 0}, //"??55",
+ {56, 0}, //"??56",
+ {57, 0}, //"??57",
+ {58, 0}, //"??58",
+ {59, 0}, //"??59",
+
+ {60, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold", chp.fBold 0,1,
+ //128, or 129 byte
+ {61, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic", chp.fItalic
+ //0,1, 128, or 129 byte
+ {62, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike", chp.fStrike
+ //0,1, 128, or 129 byte
+ {63, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline", chp.fOutline
+ //0,1, 128, or 129 byte
+ {64, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow", chp.fShadow
+ //0,1, 128, or 129 byte
+ {65, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps",
+ //chp.fSmallCaps 0,1, 128, or
+ //129 byte
+ {66, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps", chp.fCaps 0,1,
+ //128, or 129 byte
+ {67, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish", chp.fVanish
+ //0,1, 128, or 129 byte
+ {68, &SwWW8ImplReader::Read_FontCode}, //"sprmCFtc", chp.ftc ftc word
+ {69, &SwWW8ImplReader::Read_Underline}, // "sprmCKul", chp.kul kul byte
+ {70, 0}, //"sprmCSizePos", chp.hps,
+ //chp.hpsPos 3 bytes
+ {71, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace",
+ //chp.dxaSpace dxa word
+ {72, &SwWW8ImplReader::Read_Language}, //"sprmCLid", chp.lid LID word
+ {73, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco", chp.ico ico byte
+ {74, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps", chp.hps hps word!
+ {75, 0}, //"sprmCHpsInc", chp.hps byte
+ {76, &SwWW8ImplReader::Read_SubSuperProp}, //"sprmCHpsPos", chp.hpsPos
+ //hps byte
+ {77, 0}, //"sprmCHpsPosAdj", chp.hpsPos
+ //hps byte
+ {78, &SwWW8ImplReader::Read_Majority}, //"?sprmCMajority", chp.fBold,
+ //chp.fItalic, chp.fSmallCaps
+ {80, &SwWW8ImplReader::Read_BoldBiDiUsw}, //sprmCFBoldBi
+ {81, &SwWW8ImplReader::Read_BoldBiDiUsw}, //sprmCFItalicBi
+ {82, &SwWW8ImplReader::Read_FontCode}, //sprmCFtcBi
+ {83, &SwWW8ImplReader::Read_Language}, //sprmClidBi
+ {84, &SwWW8ImplReader::Read_TxtColor}, //sprmCIcoBi
+ {85, &SwWW8ImplReader::Read_FontSize}, //sprmCHpsBi
+ {86, 0}, //sprmCFBiDi
+ {87, 0}, //sprmCFDiacColor
+ {94, 0}, //"sprmPicBrcl", pic.brcl brcl
+ //(see PIC structure
+ //definition) byte
+ {95, 0}, //"sprmPicScale", pic.mx,
+ //pic.my, pic.dxaCropleft,
+ {96, 0}, //"sprmPicBrcTop", pic.brcTop
+ //BRC word
+ {97, 0}, //"sprmPicBrcLeft",
+ //pic.brcLeft BRC word
+ {98, 0}, //"sprmPicBrcBottom",
+ //pic.brcBottom BRC word
+ {99, 0} //"sprmPicBrcRight",
+ };
+
+ static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
+ return &aSprmSrch;
+}
+
+const wwSprmDispatcher *GetWW6SprmDispatcher()
+{
+ static SprmReadInfo aSprms[] =
+ {
+ {0, 0}, // "0" Default bzw. Error
+ //wird uebersprungen! ,
+ {2, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd", pap.istd
+ //(style code)
+ {3, 0}, //"sprmPIstdPermute", pap.istd
+ //permutation
+ {4, 0}, //"sprmPIncLv1",
+ //pap.istddifference
+ {5, &SwWW8ImplReader::Read_Justify}, //"sprmPJc", pap.jc
+ //(justification)
+ {6, 0}, //"sprmPFSideBySide",
+ //pap.fSideBySide
+ {7, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep", pap.fKeep
+ {8, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow ",
+ //pap.fKeepFollow
+ {9, &SwWW8ImplReader::Read_BreakBefore}, //"sprmPPageBreakBefore",
+ //pap.fPageBreakBefore
+ {10, 0}, //"sprmPBrcl", pap.brcl
+ {11, 0}, //"sprmPBrcp ", pap.brcp
+ {12, &SwWW8ImplReader::Read_ANLevelDesc}, //"sprmPAnld", pap.anld (ANLD
+ //structure)
+ {13, &SwWW8ImplReader::Read_ANLevelNo}, //"sprmPNLvlAnm", pap.nLvlAnm
+ //nn
+ {14, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb", ap.fNoLnn
+ {15, &SwWW8ImplReader::Read_Tab}, //"?sprmPChgTabsPapx",
+ //pap.itbdMac, ...
+ {16, &SwWW8ImplReader::Read_LR}, //"sprmPDxaRight", pap.dxaRight
+ {17, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft", pap.dxaLeft
+ {18, 0}, //"sprmPNest", pap.dxaLeft
+ {19, &SwWW8ImplReader::Read_LR}, //"sprmPDxaLeft1", pap.dxaLeft1
+ {20, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine", pap.lspd
+ //an LSPD
+ {21, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore",
+ //pap.dyaBefore
+ {22, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter", pap.dyaAfter
+ {23, 0}, //"?sprmPChgTabs", pap.itbdMac,
+ //pap.rgdxaTab, ...
+ {24, 0}, //"sprmPFInTable", pap.fInTable
+ {25, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPTtp", pap.fTtp
+ {26, 0}, //"sprmPDxaAbs", pap.dxaAbs
+ {27, 0}, //"sprmPDyaAbs", pap.dyaAbs
+ {28, 0}, //"sprmPDxaWidth", pap.dxaWidth
+ {29, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc", pap.pcHorz,
+ //pap.pcVert
+ {30, 0}, //"sprmPBrcTop10", pap.brcTop
+ //BRC10
+ {31, 0}, //"sprmPBrcLeft10",
+ //pap.brcLeft BRC10
+ {32, 0}, //"sprmPBrcBottom10",
+ //pap.brcBottom BRC10
+ {33, 0}, //"sprmPBrcRight10",
+ //pap.brcRight BRC10
+ {34, 0}, //"sprmPBrcBetween10",
+ //pap.brcBetween BRC10
+ {35, 0}, //"sprmPBrcBar10", pap.brcBar
+ //BRC10
+ {36, 0}, //"sprmPFromText10",
+ //pap.dxaFromText dxa
+ {37, 0}, //"sprmPWr", pap.wr wr
+ {38, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop", pap.brcTop BRC
+ {39, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft",
+ //pap.brcLeft BRC
+ {40, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom",
+ //pap.brcBottom BRC
+ {41, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight",
+ //pap.brcRight BRC
+ {42, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween",
+ //pap.brcBetween BRC
+ {43, 0}, //"sprmPBrcBar", pap.brcBar
+ //BRC word
+ {44, &SwWW8ImplReader::Read_Hyphenation}, //"sprmPFNoAutoHyph",
+ //pap.fNoAutoHyph
+ {45, 0}, //"sprmPWHeightAbs",
+ //pap.wHeightAbs w
+ {46, 0}, //"sprmPDcs", pap.dcs DCS
+ {47, &SwWW8ImplReader::Read_Shade}, //"sprmPShd", pap.shd SHD
+ {48, 0}, //"sprmPDyaFromText",
+ //pap.dyaFromText dya
+ {49, 0}, //"sprmPDxaFromText",
+ //pap.dxaFromText dxa
+ {50, 0}, //"sprmPFLocked", pap.fLocked
+ //0 or 1 byte
+ {51, &SwWW8ImplReader::Read_WidowControl}, //"sprmPFWidowControl",
+ //pap.fWidowControl 0 or 1 byte
+ {52, 0}, //"?sprmPRuler 52",
+ {53, 0}, //"??53",
+ {54, 0}, //"??54",
+ {55, 0}, //"??55",
+ {56, 0}, //"??56",
+ {57, 0}, //"??57",
+ {58, 0}, //"??58",
+ {59, 0}, //"??59",
+ {60, 0}, //"??60",
+ {61, 0}, //"??61",
+ {62, 0}, //"??62",
+ {63, 0}, //"??63",
+ {64, &SwWW8ImplReader::Read_ParaBiDi}, //"rtl bidi ?
+ {65, &SwWW8ImplReader::Read_CFRMarkDel}, //"sprmCFStrikeRM",
+ //chp.fRMarkDel 1 or 0 bit
+ {66, &SwWW8ImplReader::Read_CFRMark}, //"sprmCFRMark", chp.fRMark
+ //1 or 0 bit
+ {67, &SwWW8ImplReader::Read_FldVanish}, //"sprmCFFldVanish",
+ //chp.fFldVanish 1 or 0 bit
+ {68, &SwWW8ImplReader::Read_PicLoc}, //"sprmCPicLocation",
+ //chp.fcPic and chp.fSpec
+ {69, 0}, //"sprmCIbstRMark",
+ //chp.ibstRMark index into
+ //sttbRMark
+ {70, 0}, //"sprmCDttmRMark", chp.dttm
+ //DTTM long
+ {71, 0}, //"sprmCFData", chp.fData 1 or
+ //0 bit
+ {72, 0}, //"sprmCRMReason",
+ //chp.idslRMReason an index to
+ //a table
+ {73, &SwWW8ImplReader::Read_CharSet}, //"sprmCChse", chp.fChsDiff
+ //and chp.chse 3 bytes
+ {74, &SwWW8ImplReader::Read_Symbol}, //"sprmCSymbol", chp.fSpec,
+ //chp.chSym and chp.ftcSym
+ {75, &SwWW8ImplReader::Read_Obj}, //"sprmCFOle2", chp.fOle2 1
+ //or 0 bit
+ {76, 0}, //"??76",
+ {77, 0}, //"??77",
+ {78, 0}, //"??78",
+ {79, 0}, //"??79",
+ {80, &SwWW8ImplReader::Read_CColl}, //"sprmCIstd", chp.istd istd,
+ //see stylesheet definition
+ //short
+ {81, 0}, //"sprmCIstdPermute", chp.istd
+ //permutation vector
+ {82, 0}, //"sprmCDefault", whole CHP
+ //none variable length
+ {83, 0}, //"sprmCPlain", whole CHP
+ //none 0
+ {84, 0}, //"??84",
+ {85, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold", chp.fBold 0,1,
+ //128, or 129 byte
+ {86, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic", chp.fItalic
+ //0,1, 128, or 129 byte
+ {87, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike", chp.fStrike
+ //0,1, 128, or 129 byte
+ {88, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline", chp.fOutline
+ //0,1, 128, or 129 byte
+ {89, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow", chp.fShadow
+ //0,1, 128, or 129 byte
+ {90, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps",
+ //chp.fSmallCaps 0,1, 128, or
+ //129 byte
+ {91, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps", chp.fCaps 0,1,
+ //128, or 129 byte
+ {92, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish", chp.fVanish
+ //0,1, 128, or 129 byte
+ {93, &SwWW8ImplReader::Read_FontCode}, //"sprmCFtc", chp.ftc ftc word
+ {94, &SwWW8ImplReader::Read_Underline}, // "sprmCKul", chp.kul kul byte
+ {95, 0}, //"sprmCSizePos", chp.hps,
+ //chp.hpsPos 3 bytes
+ {96, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace",
+ //chp.dxaSpace dxa word
+ {97, &SwWW8ImplReader::Read_Language}, //"sprmCLid", chp.lid LID word
+ {98, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco", chp.ico ico byte
+ {99, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps", chp.hps hps word!
+ {100, 0}, //"sprmCHpsInc", chp.hps byte
+ {101, &SwWW8ImplReader::Read_SubSuperProp}, //"sprmCHpsPos", chp.hpsPos
+ //hps byte
+ {102, 0}, //"sprmCHpsPosAdj", chp.hpsPos
+ //hps byte
+ {103, &SwWW8ImplReader::Read_Majority}, //"?sprmCMajority", chp.fBold,
+ //chp.fItalic, chp.fSmallCaps
+ {104, &SwWW8ImplReader::Read_SubSuper}, //"sprmCIss", chp.iss iss byte
+ {105, 0}, //"sprmCHpsNew50", chp.hps hps
+ //variable width, length
+ //always recorded as 2
+ {106, 0}, //"sprmCHpsInc1", chp.hps
+ //complex variable width,
+ //length always recorded as 2
+ {107, &SwWW8ImplReader::Read_FontKern}, //"sprmCHpsKern", chp.hpsKern
+ //hps short
+ {108, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority50", chp.fBold,
+ //chp.fItalic, chp.fSmallCaps,
+ // chp.fVanish, ...
+ {109, 0}, //"sprmCHpsMul", chp.hps
+ //percentage to grow hps short
+ {110, 0}, //"sprmCCondHyhen", chp.ysri
+ //ysri short
+ {111, &SwWW8ImplReader::Read_FontCode}, //ww7 font
+ {112, &SwWW8ImplReader::Read_FontCode}, //ww7 CJK font
+ {113, &SwWW8ImplReader::Read_FontCode}, //ww7 rtl font
+ {114, &SwWW8ImplReader::Read_Language}, //ww7 lid
+ {115, &SwWW8ImplReader::Read_TxtColor}, //ww7 rtl colour ?
+ {116, &SwWW8ImplReader::Read_FontSize},
+ {117, &SwWW8ImplReader::Read_Special}, //"sprmCFSpec", chp.fSpec 1
+ //or 0 bit
+ {118, &SwWW8ImplReader::Read_Obj}, //"sprmCFObj", chp.fObj 1 or 0
+ //bit
+ {119, 0}, //"sprmPicBrcl", pic.brcl brcl
+ //(see PIC structure
+ //definition) byte
+ {120, 0}, //"sprmPicScale", pic.mx,
+ //pic.my, pic.dxaCropleft,
+ {121, 0}, //"sprmPicBrcTop", pic.brcTop
+ //BRC word
+ {122, 0}, //"sprmPicBrcLeft",
+ //pic.brcLeft BRC word
+ {123, 0}, //"sprmPicBrcBottom",
+ //pic.brcBottom BRC word
+ {124, 0}, //"sprmPicBrcRight",
+ //pic.brcRight BRC word
+ {125, 0}, //"??125",
+ {126, 0}, //"??126",
+ {127, 0}, //"??127",
+ {128, 0}, //"??128",
+ {129, 0}, //"??129",
+ {130, 0}, //"??130",
+ {131, 0}, //"sprmSScnsPgn", sep.cnsPgn
+ //cns byte
+ {132, 0}, //"sprmSiHeadingPgn",
+ //sep.iHeadingPgn heading
+ //number level byte
+ {133, &SwWW8ImplReader::Read_OLST}, //"sprmSOlstAnm", sep.olstAnm
+ //OLST variable length
+ {134, 0}, //"??135",
+ {135, 0}, //"??135",
+ {136, 0}, //"sprmSDxaColWidth",
+ //sep.rgdxaColWidthSpacing
+ //complex 3 bytes
+ {137, 0}, //"sprmSDxaColSpacing",
+ //sep.rgdxaColWidthSpacing
+ //complex 3 bytes
+ {138, 0}, //"sprmSFEvenlySpaced",
+ //sep.fEvenlySpaced 1 or 0 byte
+ {139, 0}, //"sprmSFProtected",
+ //sep.fUnlocked 1 or 0 byte
+ {140, 0}, //"sprmSDmBinFirst",
+ //sep.dmBinFirst word
+ {141, 0}, //"sprmSDmBinOther",
+ //sep.dmBinOther word
+ {142, 0}, //"sprmSBkc", sep.bkc bkc
+ //byte BreakCode
+ {143, 0}, //"sprmSFTitlePage",
+ //sep.fTitlePage 0 or 1 byte
+ {144, 0}, //"sprmSCcolumns", sep.ccolM1
+ //# of cols - 1 word
+ {145, 0}, //"sprmSDxaColumns",
+ //sep.dxaColumns dxa word
+ {146, 0}, //"sprmSFAutoPgn",
+ //sep.fAutoPgn obsolete byte
+ {147, 0}, //"sprmSNfcPgn", sep.nfcPgn
+ //nfc byte
+ {148, 0}, //"sprmSDyaPgn", sep.dyaPgn
+ //dya short
+ {149, 0}, //"sprmSDxaPgn", sep.dxaPgn
+ //dya short
+ {150, 0}, //"sprmSFPgnRestart",
+ //sep.fPgnRestart 0 or 1 byte
+ {151, 0}, //"sprmSFEndnote", sep.fEndnote
+ //0 or 1 byte
+ {152, 0}, //"sprmSLnc", sep.lnc lnc byte
+ {153, 0}, //"sprmSGprfIhdt", sep.grpfIhdt
+ //grpfihdt byte
+ {154, 0}, //"sprmSNLnnMod", sep.nLnnMod
+ //non-neg int. word
+ {155, 0}, //"sprmSDxaLnn", sep.dxaLnn
+ //dxa word
+ {156, 0}, //"sprmSDyaHdrTop",
+ //sep.dyaHdrTop dya word
+ {157, 0}, //"sprmSDyaHdrBottom",
+ //sep.dyaHdrBottom dya word
+ {158, 0}, //"sprmSLBetween",
+ //sep.fLBetween 0 or 1 byte
+ {159, 0}, //"sprmSVjc", sep.vjc vjc byte
+ {160, 0}, //"sprmSLnnMin", sep.lnnMin
+ //lnn word
+ {161, 0}, //"sprmSPgnStart", sep.pgnStart
+ //pgn word
+ {162, 0}, //"sprmSBOrientation",
+ //sep.dmOrientPage dm byte
+ {163, 0}, //"?SprmSBCustomize 163", ?
+ {164, 0}, //"sprmSXaPage", sep.xaPage xa
+ //word
+ {165, 0}, //"sprmSYaPage", sep.yaPage ya
+ //word
+ {166, 0}, //"sprmSDxaLeft", sep.dxaLeft
+ //dxa word
+ {167, 0}, //"sprmSDxaRight", sep.dxaRight
+ //dxa word
+ {168, 0}, //"sprmSDyaTop", sep.dyaTop //dya word
+ {169, 0}, //"sprmSDyaBottom",
+ //sep.dyaBottom dya word
+ {170, 0}, //"sprmSDzaGutter",
+ //sep.dzaGutter dza word
+ {171, 0}, //"sprmSDMPaperReq",
+ //sep.dmPaperReq dm word
+ {172, 0}, //"??172",
+ {173, 0}, //"??173",
+ {174, 0}, //"??174",
+ {175, 0}, //"??175",
+ {176, 0}, //"??176",
+ {177, 0}, //"??177",
+ {178, 0}, //"??178",
+ {179, 0}, //"??179",
+ {180, 0}, //"??180",
+ {181, 0}, //"??181",
+ {182, 0}, //"sprmTJc", tap.jc jc word
+ //(low order byte is
+ //significant)
+ {183, 0}, //"sprmTDxaLeft",
+ //tap.rgdxaCenter dxa word
+ {184, 0}, //"sprmTDxaGapHalf",
+ //tap.dxaGapHalf,
+ //tap.rgdxaCenter dxa word
+ {185, 0}, //"sprmTFCantSplit"
+ //tap.fCantSplit 1 or 0 byte
+ {186, 0}, //"sprmTTableHeader",
+ //tap.fTableHeader 1 or 0 byte
+ {187, 0}, //"sprmTTableBorders",
+ //tap.rgbrcTable complex
+ //12 bytes
+ {188, 0}, //"sprmTDefTable10",
+ //tap.rgdxaCenter, tap.rgtc
+ //complex variable length
+ {189, 0}, //"sprmTDyaRowHeight",
+ //tap.dyaRowHeight dya word
+ {190, 0}, //"?sprmTDefTable", tap.rgtc
+ //complex
+ {191, 0}, //"?sprmTDefTableShd",
+ //tap.rgshd complex
+ {192, 0}, //"sprmTTlp", tap.tlp TLP
+ //4 bytes
+ {193, 0}, //"sprmTSetBrc",
+ //tap.rgtc[].rgbrc complex
+ //5 bytes
+ {194, 0}, //"sprmTInsert",
+ //tap.rgdxaCenter,
+ //tap.rgtc complex 4 bytes
+ {195, 0}, //"sprmTDelete",
+ //tap.rgdxaCenter,
+ //tap.rgtc complex word
+ {196, 0}, //"sprmTDxaCol",
+ //tap.rgdxaCenter complex
+ //4 bytes
+ {197, 0}, //"sprmTMerge",
+ //tap.fFirstMerged,
+ //tap.fMerged complex word
+ {198, 0}, //"sprmTSplit",
+ //tap.fFirstMerged,
+ //tap.fMerged complex word
+ {199, 0}, //"sprmTSetBrc10",
+ //tap.rgtc[].rgbrc complex
+ //5 bytes
+ {200, 0}, //"sprmTSetShd", tap.rgshd
+ //complex 4 bytes
+ {207, 0}, //dunno
+ };
+
+ static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
+ return &aSprmSrch;
+}
+
+const wwSprmDispatcher *GetWW8SprmDispatcher()
+{
+ static SprmReadInfo aSprms[] =
+ {
+ {0, 0}, // "0" Default bzw. Error
+
+ {0x4600, &SwWW8ImplReader::Read_StyleCode}, //"sprmPIstd" pap.istd;istd
+ //(style code);short;
+ {0xC601, 0}, //"sprmPIstdPermute" pap.istd;
+ //permutation vector;
+ //variable length;
+ {0x2602, 0}, //"sprmPIncLvl" pap.istd,
+ //pap.lvl;difference between
+ //istd of base PAP and istd of
+ //PAP to be produced; byte;
+ {0x2403, &SwWW8ImplReader::Read_Justify}, //"sprmPJc" pap.jc;jc
+ //(justification);byte;
+ {0x2404, 0}, //"sprmPFSideBySide"
+ //pap.fSideBySide;0 or 1;byte;
+ {0x2405, &SwWW8ImplReader::Read_KeepLines}, //"sprmPFKeep" pap.fKeep;0 or
+ //1;byte;
+ {0x2406, &SwWW8ImplReader::Read_KeepParas}, //"sprmPFKeepFollow"
+ //pap.fKeepFollow;0 or 1;byte;
+ {0x2407, &SwWW8ImplReader::Read_BreakBefore},//"sprmPFPageBreakBefore"
+ //pap.fPageBreakBefore;0 or 1;
+ //byte;
+ {0x2408, 0}, //"sprmPBrcl" pap.brcl;brcl;
+ //byte;
+ {0x2409, 0}, //"sprmPBrcp" pap.brcp;brcp;
+ //byte;
+ {0x260A, &SwWW8ImplReader::Read_ListLevel}, //"sprmPIlvl" pap.ilvl;ilvl;
+ //byte;
+ {0x460B, &SwWW8ImplReader::Read_LFOPosition},//"sprmPIlfo" pap.ilfo;ilfo
+ //(list index) ;short;
+ {0x240C, &SwWW8ImplReader::Read_NoLineNumb}, //"sprmPFNoLineNumb"
+ //pap.fNoLnn;0 or 1;byte;
+ {0xC60D, &SwWW8ImplReader::Read_Tab}, //"sprmPChgTabsPapx"
+ //pap.itbdMac, pap.rgdxaTab,
+ //pap.rgtbd;complex;variable
+ //length
+ {0x840E, &SwWW8ImplReader::Read_LR}, //Word 97 version of "sprmPDxaRight" pap.dxaRight;
+ //dxa;word;
+ {0x840F, &SwWW8ImplReader::Read_LR}, //Apparently Word 97 version of "sprmPDxaLeft" pap.dxaLeft;
+ //dxa;word;
+ {0x4610, 0}, //"sprmPNest" pap.dxaLeft;
+ //dxa;word;
+ {0x8411, &SwWW8ImplReader::Read_LR}, //Word 97 version of "sprmPDxaLeft1" pap.dxaLeft1;
+ //dxa;word;
+ {0x6412, &SwWW8ImplReader::Read_LineSpace}, //"sprmPDyaLine" pap.lspd;
+ //an LSPD, a long word
+ //structure consisting of a
+ //short of dyaLine followed by
+ //a short of fMultLinespace;
+ //long;
+ {0xA413, &SwWW8ImplReader::Read_UL}, //"sprmPDyaBefore"
+ //pap.dyaBefore;dya;word;
+ {0xA414, &SwWW8ImplReader::Read_UL}, //"sprmPDyaAfter" pap.dyaAfter;
+ //dya;word;
+ {0xC615, 0}, //"sprmPChgTabs" pap.itbdMac,
+ //pap.rgdxaTab, pap.rgtbd;
+ //complex;variable length;
+ {0x2416, 0}, //"sprmPFInTable" pap.fInTable;
+ //0 or 1;byte;
+ {0x2417, &SwWW8ImplReader::Read_TabRowEnd}, //"sprmPFTtp" pap.fTtp;0 or 1;
+ //byte;
+ {0x8418, 0}, //"sprmPDxaAbs" pap.dxaAbs;dxa;
+ //word;
+ {0x8419, 0}, //"sprmPDyaAbs" pap.dyaAbs;dya;
+ //word;
+ {0x841A, 0}, //"sprmPDxaWidth" pap.dxaWidth;
+ //dxa;word;
+ {0x261B, &SwWW8ImplReader::Read_ApoPPC}, //"sprmPPc" pap.pcHorz,
+ //pap.pcVert;complex;byte;
+ {0x461C, 0}, //"sprmPBrcTop10" pap.brcTop;
+ //BRC10;word;
+ {0x461D, 0}, //"sprmPBrcLeft10" pap.brcLeft;
+ //BRC10;word;
+ {0x461E, 0}, //"sprmPBrcBottom10"
+ //pap.brcBottom;BRC10;word;
+ {0x461F, 0}, //"sprmPBrcRight10"
+ //pap.brcRight;BRC10;word;
+ {0x4620, 0}, //"sprmPBrcBetween10"
+ //pap.brcBetween;BRC10;word;
+ {0x4621, 0}, //"sprmPBrcBar10" pap.brcBar;
+ //BRC10;word;
+ {0x4622, 0}, //"sprmPDxaFromText10"
+ //pap.dxaFromText;dxa;word;
+ {0x2423, 0}, //"sprmPWr" pap.wr;wr;byte;
+ {0x6424, &SwWW8ImplReader::Read_Border}, //"sprmPBrcTop" pap.brcTop;BRC;
+ //long;
+ {0x6425, &SwWW8ImplReader::Read_Border}, //"sprmPBrcLeft" pap.brcLeft;
+ //BRC;long;
+ {0x6426, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBottom"
+ //pap.brcBottom;BRC;long;
+ {0x6427, &SwWW8ImplReader::Read_Border}, //"sprmPBrcRight" pap.brcRight;
+ //BRC;long;
+ {0x6428, &SwWW8ImplReader::Read_Border}, //"sprmPBrcBetween"
+ //pap.brcBetween;BRC;long;
+ {0x6629, 0}, //"sprmPBrcBar" pap.brcBar;BRC;
+ //long;
+ {0x242A, &SwWW8ImplReader::Read_Hyphenation},//"sprmPFNoAutoHyph"
+ //pap.fNoAutoHyph;0 or 1;byte;
+ {0x442B, 0}, //"sprmPWHeightAbs"
+ //pap.wHeightAbs;w;word;
+ {0x442C, 0}, //"sprmPDcs" pap.dcs;DCS;short;
+ {0x442D, &SwWW8ImplReader::Read_Shade}, //"sprmPShd" pap.shd;SHD;word;
+ {0x842E, 0}, //"sprmPDyaFromText"
+ //pap.dyaFromText;dya;word;
+ {0x842F, 0}, //"sprmPDxaFromText"
+ //pap.dxaFromText;dxa;word;
+ {0x2430, 0}, //"sprmPFLocked" pap.fLocked;
+ //0 or 1;byte;
+ {0x2431, &SwWW8ImplReader::Read_WidowControl},//"sprmPFWidowControl"
+ //pap.fWidowControl;0 or 1;byte
+ {0xC632, 0}, //"sprmPRuler" variable length;
+ {0x2433, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFKinsoku" pap.fKinsoku;
+ //0 or 1;byte;
+ {0x2434, 0}, //"sprmPFWordWrap"
+ //pap.fWordWrap;0 or 1;byte;
+ {0x2435, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFOverflowPunct"
+ //pap.fOverflowPunct; 0 or 1;
+ //byte;
+ {0x2436, 0}, //"sprmPFTopLinePunct"
+ //pap.fTopLinePunct;0 or 1;byte
+ {0x2437, &SwWW8ImplReader::Read_BoolItem}, //"sprmPFAutoSpaceDE"
+ //pap.fAutoSpaceDE;0 or 1;byte;
+ {0x2438, 0}, //"sprmPFAutoSpaceDN"
+ //pap.fAutoSpaceDN;0 or 1;byte;
+ {0x4439, &SwWW8ImplReader::Read_AlignFont}, //"sprmPWAlignFont"
+ //pap.wAlignFont;iFa; word;
+ {0x443A, 0}, //"sprmPFrameTextFlow"
+ //pap.fVertical pap.fBackward
+ //pap.fRotateFont;complex; word
+ {0x243B, 0}, //"sprmPISnapBaseLine" obsolete
+ //not applicable in Word97
+ //and later versions;;byte;
+ {0xC63E, &SwWW8ImplReader::Read_ANLevelDesc},//"sprmPAnld" pap.anld;;
+ //variable length;
+ {0xC63F, 0}, //"sprmPPropRMark"
+ //pap.fPropRMark;complex;
+ //variable length;
+ {0x2640, &SwWW8ImplReader::Read_POutLvl}, //"sprmPOutLvl" pap.lvl;has no
+ //effect if pap.istd is < 1 or
+ //is > 9;byte;
+ {0x2441, &SwWW8ImplReader::Read_ParaBiDi}, //"sprmPFBiDi" ;;byte;
+ {0x2443, 0}, //"sprmPFNumRMIns"
+ //pap.fNumRMIns;1 or 0;bit;
+ {0x2444, 0}, //"sprmPCrLf" ;;byte;
+ {0xC645, 0}, //"sprmPNumRM" pap.numrm;;
+ //variable length;
+ {0x6645, 0}, //"sprmPHugePapx" ;fc in the
+ //data stream to locate the
+ //huge grpprl; long;
+ {0x6646, 0}, //"sprmPHugePapx" ;fc in the
+ //data stream to locate the
+ //huge grpprl; long;
+ {0x2447, &SwWW8ImplReader::Read_UsePgsuSettings},//"sprmPFUsePgsuSettings"
+ //pap.fUsePgsuSettings;1 or 0;
+ //byte;
+ {0x2448, 0}, //"sprmPFAdjustRight"
+ //pap.fAdjustRight;1 or 0;byte;
+ {0x0800, &SwWW8ImplReader::Read_CFRMarkDel}, //"sprmCFRMarkDel"
+ //chp.fRMarkDel;1 or 0;bit;
+ {0x0801, &SwWW8ImplReader::Read_CFRMark}, //"sprmCFRMark" chp.fRMark;1
+ //or 0;bit;
+ {0x0802, &SwWW8ImplReader::Read_FldVanish}, //"sprmCFFldVanish"
+ //chp.fFldVanish;1 or 0;bit;
+ {0x6A03, &SwWW8ImplReader::Read_PicLoc}, //"sprmCPicLocation" chp.fcPic
+ //and chp.fSpec;variable
+ //length, length recorded is
+ //always 4;
+ {0x4804, 0}, //"sprmCIbstRMark"
+ //chp.ibstRMark;index into
+ //sttbRMark;short;
+ {0x6805, 0}, //"sprmCDttmRMark"
+ //chp.dttmRMark;DTTM;long;
+ {0x0806, 0}, //"sprmCFData" chp.fData;1 or
+ //0;bit;
+ {0x4807, 0}, //"sprmCIdslRMark"
+ //chp.idslRMReason;an index to
+ //a table of strings defined in
+ //Word 6.0 executables;short;
+ {0xEA08, &SwWW8ImplReader::Read_CharSet}, //"sprmCChs" chp.fChsDiff and
+ //chp.chse;3 bytes;
+ {0x6A09, &SwWW8ImplReader::Read_Symbol}, //"sprmCSymbol" chp.fSpec,
+ //chp.xchSym and chp.ftcSym;
+ //variable length, length
+ //recorded is always 4;
+ {0x080A, &SwWW8ImplReader::Read_Obj}, //"sprmCFOle2" chp.fOle2;1 or
+ //0;bit;
+ //0x480B, //"sprmCIdCharType", obsolete:
+ //not applicable in Word97
+ //and later versions
+ {0x2A0C, &SwWW8ImplReader::Read_CharHighlight},//"sprmCHighlight"
+ //chp.fHighlight,
+ //chp.icoHighlight;ico
+ //(fHighlight is set to 1 iff
+ //ico is not 0);byte;
+ {0x680E, &SwWW8ImplReader::Read_PicLoc}, //"sprmCObjLocation" chp.fcObj;
+ //FC;long;
+ //0x2A10, ? ? ?, //"sprmCFFtcAsciSymb"
+ {0x4A30, &SwWW8ImplReader::Read_CColl}, //"sprmCIstd" chp.istd;istd,
+ //short;
+ {0xCA31, 0}, //"sprmCIstdPermute" chp.istd;
+ //permutation vector; variable
+ //length;
+ {0x2A32, 0}, //"sprmCDefault" whole CHP;none
+ //;variable length;
+ {0x2A33, 0}, //"sprmCPlain" whole CHP;none;
+ //Laenge: 0;
+ {0x2A34, &SwWW8ImplReader::Read_Emphasis}, //"sprmCKcd"
+ {0x0835, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFBold" chp.fBold;0,1,
+ //128, or 129; byte;
+ {0x0836, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFItalic" chp.fItalic;0,
+ //1, 128, or 129; byte;
+ {0x0837, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFStrike" chp.fStrike;0,
+ //1, 128, or 129; byte;
+ {0x0838, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFOutline" chp.fOutline;
+ //0,1, 128, or 129; byte;
+ {0x0839, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFShadow" chp.fShadow;0,
+ //1, 128, or 129; byte;
+ {0x083A, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFSmallCaps"
+ //chp.fSmallCaps;0,1, 128, or
+ //129;byte;
+ {0x083B, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFCaps" chp.fCaps;0,1,
+ //128, or 129; byte;
+ {0x083C, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFVanish" chp.fVanish;0,
+ //1, 128, or 129; byte;
+ //0x4A3D, 0, //"sprmCFtcDefault" ftc, only
+ //used internally, never
+ //stored in file;word;
+ {0x2A3E, &SwWW8ImplReader::Read_Underline}, //"sprmCKul" chp.kul;kul;byte;
+ {0xEA3F, 0}, //"sprmCSizePos" chp.hps,
+ //chp.hpsPos;3 bytes;
+ {0x8840, &SwWW8ImplReader::Read_Kern}, //"sprmCDxaSpace" chp.dxaSpace;
+ //dxa;word;
+ {0x4A41, &SwWW8ImplReader::Read_Language}, //"sprmCLid" ;only used
+ //internally never stored;word;
+ {0x2A42, &SwWW8ImplReader::Read_TxtColor}, //"sprmCIco" chp.ico;ico;byte;
+ {0x4A43, &SwWW8ImplReader::Read_FontSize}, //"sprmCHps" chp.hps;hps;byte;
+ {0x2A44, 0}, //"sprmCHpsInc" chp.hps;byte;
+ {0x4845, &SwWW8ImplReader::Read_SubSuperProp},//"sprmCHpsPos" chp.hpsPos;
+ //hps; byte;
+ {0x2A46, 0}, //"sprmCHpsPosAdj" chp.hpsPos;
+ //hps; byte;
+ {0xCA47, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority" chp.fBold,
+ //chp.fItalic, chp.fSmallCaps,
+ //chp.fVanish, chp.fStrike,
+ //chp.fCaps, chp.rgftc,
+ //chp.hps, chp.hpsPos, chp.kul,
+ //chp.dxaSpace, chp.ico,
+ //chp.rglid;complex;variable
+ //length, length byte plus
+ //size of following grpprl;
+ {0x2A48, &SwWW8ImplReader::Read_SubSuper}, //"sprmCIss" chp.iss;iss;byte;
+ {0xCA49, 0}, //"sprmCHpsNew50" chp.hps;hps;
+ //variable width, length
+ //always recorded as 2;
+ {0xCA4A, 0}, //"sprmCHpsInc1" chp.hps;
+ //complex; variable width,
+ //length always recorded as 2;
+ {0x484B, &SwWW8ImplReader::Read_FontKern}, //"sprmCHpsKern" chp.hpsKern;
+ //hps;short;
+ {0xCA4C, &SwWW8ImplReader::Read_Majority}, //"sprmCMajority50" chp.fBold,
+ //chp.fItalic, chp.fSmallCaps,
+ //chp.fVanish, chp.fStrike,
+ //chp.fCaps, chp.ftc, chp.hps,
+ //chp.hpsPos, chp.kul,
+ //chp.dxaSpace, chp.ico;
+ //complex; variable length;
+ {0x4A4D, 0}, //"sprmCHpsMul" chp.hps;
+ //percentage to grow hps;short;
+ {0x484E, 0}, //"sprmCYsri" chp.ysri;ysri;
+ //short;
+ {0x4A4F, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc0" chp.rgftc[0];
+ //ftc for ASCII text; short;
+ {0x4A50, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc1" chp.rgftc[1];
+ //ftc for Far East text;short;
+ {0x4A51, &SwWW8ImplReader::Read_FontCode}, //"sprmCRgFtc2" chp.rgftc[2];
+ //ftc for non-Far East text;
+ //short;
+ {0x4852, &SwWW8ImplReader::Read_ScaleWidth}, //"sprmCCharScale"
+ {0x2A53, &SwWW8ImplReader::Read_BoldUsw}, //"sprmCFDStrike" chp.fDStrike;
+ //;byte;
+ {0x0854, &SwWW8ImplReader::Read_Relief}, //"sprmCFImprint" chp.fImprint;
+ //1 or 0;bit;
+ {0x0855, &SwWW8ImplReader::Read_Special}, //"sprmCFSpec" chp.fSpec;
+ //1 or 0;bit;
+ {0x0856, &SwWW8ImplReader::Read_Obj}, //"sprmCFObj" chp.fObj;1 or 0;
+ //bit;
+ {0xCA57, &SwWW8ImplReader::Read_CPropRMark}, //"sprmCPropRMark"
+ //chp.fPropRMark,
+ //chp.ibstPropRMark,
+ //chp.dttmPropRMark;Complex;
+ //variable length always
+ //recorded as 7 bytes;
+ {0x0858, &SwWW8ImplReader::Read_Relief}, //"sprmCFEmboss" chp.fEmboss;
+ //1 or 0;bit;
+ {0x2859, &SwWW8ImplReader::Read_TxtAnim}, //"sprmCSfxText" chp.sfxtText;
+ //text animation;byte;
+ {0x085A, &SwWW8ImplReader::Read_Bidi}, //"sprmCFBiDi"
+ {0x085B, 0}, //"sprmCFDiacColor"
+ {0x085C, &SwWW8ImplReader::Read_BoldBiDiUsw},//"sprmCFBoldBi"
+ {0x085D, &SwWW8ImplReader::Read_BoldBiDiUsw},//"sprmCFItalicBi"
+ {0x4A5E, &SwWW8ImplReader::Read_FontCode},
+ {0x485F, &SwWW8ImplReader::Read_Language}, // "sprmCLidBi"
+ //0x4A60, ? ? ?, //"sprmCIcoBi",
+ {0x4A61, &SwWW8ImplReader::Read_FontSize}, //"sprmCHpsBi"
+ {0xCA62, 0}, //"sprmCDispFldRMark"
+ //chp.fDispFldRMark,
+ //chp.ibstDispFldRMark,
+ //chp.dttmDispFldRMark ;
+ //Complex;variable length
+ //always recorded as 39 bytes;
+ {0x4863, 0}, //"sprmCIbstRMarkDel"
+ //chp.ibstRMarkDel;index into
+ //sttbRMark;short;
+ {0x6864, 0}, //"sprmCDttmRMarkDel"
+ //chp.dttmRMarkDel;DTTM;long;
+ {0x6865, 0}, //"sprmCBrc" chp.brc;BRC;long;
+ {0x4866, &SwWW8ImplReader::Read_CharShadow}, //"sprmCShd" chp.shd;SHD;short;
+ {0x4867, 0}, //"sprmCIdslRMarkDel"
+ //chp.idslRMReasonDel;an index
+ //to a table of strings
+ //defined in Word 6.0
+ //executables;short;
+ {0x0868, 0}, //"sprmCFUsePgsuSettings"
+ //chp.fUsePgsuSettings; 1 or 0;
+ //bit;
+ {0x486B, 0}, //"sprmCCpg" ;;word;
+ {0x486D, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid0" chp.rglid[0];
+ //LID: for non-Far East text;
+ //word;
+ {0x486E, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid1" chp.rglid[1];
+ //LID: for Far East text;word;
+ {0x286F, &SwWW8ImplReader::Read_IdctHint}, //"sprmCIdctHint" chp.idctHint;
+ //IDCT: byte;
+ {0x2E00, 0}, //"sprmPicBrcl" pic.brcl;brcl
+ //(see PIC structure
+ //definition);byte;
+ {0xCE01, 0}, //"sprmPicScale" pic.mx,
+ //pic.my, pic.dxaCropleft,
+ //pic.dyaCropTop
+ //pic.dxaCropRight,
+ //pic.dyaCropBottom;Complex;
+ //length byte plus 12 bytes;
+ {0x6C02, 0}, //"sprmPicBrcTop" pic.brcTop;
+ //BRC;long;
+ {0x6C03, 0}, //"sprmPicBrcLeft" pic.brcLeft;
+ //BRC;long;
+ {0x6C04, 0}, //"sprmPicBrcBottom"
+ //pic.brcBottom;BRC;long;
+ {0x6C05, 0}, //"sprmPicBrcRight"
+ //pic.brcRight;BRC;long;
+ {0x3000, 0}, //"sprmScnsPgn" sep.cnsPgn;cns;
+ //byte;
+ {0x3001, 0}, //"sprmSiHeadingPgn"
+ //sep.iHeadingPgn;heading
+ //number level;byte;
+ {0xD202, &SwWW8ImplReader::Read_OLST}, //"sprmSOlstAnm" sep.olstAnm;
+ //OLST;variable length;
+ {0xF203, 0}, //"sprmSDxaColWidth"
+ //sep.rgdxaColWidthSpacing;
+ //complex; 3 bytes;
+ {0xF204, 0}, //"sprmSDxaColSpacing"
+ //sep.rgdxaColWidthSpacing;
+ //complex; 3 bytes;
+ {0x3005, 0}, //"sprmSFEvenlySpaced"
+ //sep.fEvenlySpaced; 1 or 0;
+ //byte;
+ {0x3006, 0}, //"sprmSFProtected"
+ //sep.fUnlocked;1 or 0;byte;
+ {0x5007, 0}, //"sprmSDmBinFirst"
+ //sep.dmBinFirst;;word;
+ {0x5008, 0}, //"sprmSDmBinOther"
+ //sep.dmBinOther;;word;
+ {0x3009, 0}, //"sprmSBkc" sep.bkc;bkc;byte;
+ {0x300A, 0}, //"sprmSFTitlePage"
+ //sep.fTitlePage;0 or 1;byte;
+ {0x500B, 0}, //"sprmSCcolumns" sep.ccolM1;
+ //# of cols - 1;word;
+ {0x900C, 0}, //"sprmSDxaColumns"
+ //sep.dxaColumns;dxa;word;
+ {0x300D, 0}, //"sprmSFAutoPgn" sep.fAutoPgn;
+ //obsolete;byte;
+ {0x300E, 0}, //"sprmSNfcPgn" sep.nfcPgn;nfc;
+ //byte;
+ {0xB00F, 0}, //"sprmSDyaPgn" sep.dyaPgn;dya;
+ //short;
+ {0xB010, 0}, //"sprmSDxaPgn" sep.dxaPgn;dya;
+ //short;
+ {0x3011, 0}, //"sprmSFPgnRestart"
+ //sep.fPgnRestart;0 or 1;byte;
+ {0x3012, 0}, //"sprmSFEndnote" sep.fEndnote;
+ //0 or 1;byte;
+ {0x3013, 0}, //"sprmSLnc" sep.lnc;lnc;byte;
+ {0x3014, 0}, //"sprmSGprfIhdt" sep.grpfIhdt;
+ //grpfihdt; byte;
+ {0x5015, 0}, //"sprmSNLnnMod" sep.nLnnMod;
+ //non-neg int.;word;
+ {0x9016, 0}, //"sprmSDxaLnn" sep.dxaLnn;dxa;
+ //word;
+ {0xB017, 0}, //"sprmSDyaHdrTop"
+ //sep.dyaHdrTop;dya;word;
+ {0xB018, 0}, //"sprmSDyaHdrBottom"
+ //sep.dyaHdrBottom;dya;word;
+ {0x3019, 0}, //"sprmSLBetween"
+ //sep.fLBetween;0 or 1;byte;
+ {0x301A, 0}, //"sprmSVjc" sep.vjc;vjc;byte;
+ {0x501B, 0}, //"sprmSLnnMin" sep.lnnMin;lnn;
+ //word;
+ {0x501C, 0}, //"sprmSPgnStart" sep.pgnStart;
+ //pgn;word;
+ {0x301D, 0}, //"sprmSBOrientation"
+ //sep.dmOrientPage;dm;byte;
+ //0x301E, ? ? ?, //"sprmSBCustomize"
+ {0xB01F, 0}, //"sprmSXaPage" sep.xaPage;xa;
+ //word;
+ {0xB020, 0}, //"sprmSYaPage" sep.yaPage;ya;
+ //word;
+ {0x2205, 0}, //"sprmSDxaLeft" sep.dxaLeft;
+ //dxa;word;
+ {0xB022, 0}, //"sprmSDxaRight" sep.dxaRight;
+ //dxa;word;
+ {0x9023, 0}, //"sprmSDyaTop" sep.dyaTop;dya;
+ //word;
+ {0x9024, 0}, //"sprmSDyaBottom"
+ //sep.dyaBottom;dya;word;
+ {0xB025, 0}, //"sprmSDzaGutter"
+ //sep.dzaGutter;dza;word;
+ {0x5026, 0}, //"sprmSDmPaperReq"
+ //sep.dmPaperReq;dm;word;
+ {0xD227, 0}, //"sprmSPropRMark"
+ //sep.fPropRMark,
+ //sep.ibstPropRMark,
+ //sep.dttmPropRMark ;complex;
+ //variable length always
+ //recorded as 7 bytes;
+ //0x3228, ? ? ?, //"sprmSFBiDi",
+ //0x3229, ? ? ?, //"sprmSFFacingCol"
+ {0x322A, 0}, //"sprmSFRTLGutter", set to 1
+ //if gutter is on the right.
+ {0x702B, 0}, //"sprmSBrcTop" sep.brcTop;BRC;
+ //long;
+ {0x702C, 0}, //"sprmSBrcLeft" sep.brcLeft;
+ //BRC;long;
+ {0x702D, 0}, //"sprmSBrcBottom"
+ //sep.brcBottom;BRC;long;
+ {0x702E, 0}, //"sprmSBrcRight" sep.brcRight;
+ //BRC;long;
+ {0x522F, 0}, //"sprmSPgbProp" sep.pgbProp;
+ //word;
+ {0x7030, 0}, //"sprmSDxtCharSpace"
+ //sep.dxtCharSpace;dxt;long;
+ {0x9031, 0}, //"sprmSDyaLinePitch"
+ //sep.dyaLinePitch;dya;
+ //WRONG:long; RIGHT:short; !
+ //0x5032, ? ? ?, //"sprmSClm"
+ {0x5033, 0}, //"sprmSTextFlow"
+ //sep.wTextFlow;complex ;short
+ {0x5400, 0}, //"sprmTJc" tap.jc;jc;word (low
+ //order byte is significant);
+ {0x9601, 0}, //"sprmTDxaLeft"
+ //tap.rgdxaCenter; dxa; word;
+ {0x9602, 0}, //"sprmTDxaGapHalf"
+ //tap.dxaGapHalf,
+ //tap.rgdxaCenter; dxa; word;
+ {0x3403, 0}, //"sprmTFCantSplit"
+ //tap.fCantSplit;1 or 0;byte;
+ {0x3404, 0}, //"sprmTTableHeader"
+ //tap.fTableHeader;1 or 0;byte;
+ {0x3466, 0}, //"sprmTFCantSplit90"
+ //tap.fCantSplit90;1 or 0;byte;
+ {0xD605, 0}, //"sprmTTableBorders"
+ //tap.rgbrcTable;complex;
+ //24 bytes;
+ {0xD606, 0}, //"sprmTDefTable10"
+ //tap.rgdxaCenter,
+ //tap.rgtc;complex; variable
+ //length;
+ {0x9407, 0}, //"sprmTDyaRowHeight"
+ //tap.dyaRowHeight;dya;word;
+ {0xD608, 0}, //"sprmTDefTable"
+ //tap.rgtc;complex
+ {0xD609, 0}, //"sprmTDefTableShd"
+ //tap.rgshd;complex
+ {0x740A, 0}, //"sprmTTlp" tap.tlp;TLP;
+ //4 bytes;
+ //0x560B, ? ? ?, //"sprmTFBiDi"
+ //0x740C, ? ? ?, //"sprmTHTMLProps"
+ {0xD620, 0}, //"sprmTSetBrc"
+ //tap.rgtc[].rgbrc;complex;
+ //5 bytes;
+ {0x7621, 0}, //"sprmTInsert"
+ //tap.rgdxaCenter,
+ //tap.rgtc;complex ;4 bytes;
+ {0x5622, 0}, //"sprmTDelete"
+ //tap.rgdxaCenter,
+ //tap.rgtc;complex ;word;
+ {0x7623, 0}, //"sprmTDxaCol"
+ //tap.rgdxaCenter;complex;
+ //4 bytes;
+ {0x5624, 0}, //"sprmTMerge"
+ //tap.fFirstMerged,
+ //tap.fMerged;complex; word;
+ {0x5625, 0}, //"sprmTSplit"
+ //tap.fFirstMerged,
+ //tap.fMerged;complex ;word;
+ {0xD626, 0}, //"sprmTSetBrc10"
+ //tap.rgtc[].rgbrc;complex;
+ //5 bytes;
+ {0x7627, 0}, //"sprmTSetShd" tap.rgshd;
+ //complex; 4 bytes;
+ {0x7628, 0}, //"sprmTSetShdOdd"
+ //tap.rgshd;complex;4 bytes;
+ {0x7629, 0}, //"sprmTTextFlow"
+ //tap.rgtc[].fVertical
+ //tap.rgtc[].fBackward
+ //tap.rgtc[].fRotateFont
+ //0 or 10 or 10 or 1;word;
+ //0xD62A, ? ? ? , //"sprmTDiagLine"
+ {0xD62B, 0}, //"sprmTVertMerge"
+ //tap.rgtc[].vertMerge;complex;
+ //variable length always
+ //recorded as 2 bytes;
+ {0xD62C, 0}, //"sprmTVertAlign"
+ //tap.rgtc[].vertAlign;complex
+ //variable length always
+ //recorded as 3 byte;
+ {0xCA78, &SwWW8ImplReader::Read_DoubleLine_Rotate},
+ {0x6649, 0}, //undocumented
+ {0xF614, 0}, //"sprmTTableWidth"
+ //recorded as 3 bytes;
+ {0xD612, 0}, //undocumented
+ {0xD613, 0}, //undocumented
+ {0xD61A, 0}, //undocumented
+ {0xD61B, 0}, //undocumented
+ {0xD61C, 0}, //undocumented
+ {0xD61D, 0}, //undocumented
+ {0xD634, 0}, //undocumented
+ {0xD632, 0}, //undocumented
+ {0xD238, 0}, //undocumented sep
+ {0xC64E, 0}, //undocumented
+ {0xC64F, 0}, //undocumented
+ {0xC650, 0}, //undocumented
+ {0xC651, 0}, //undocumented
+ {0xF661, 0}, //undocumented
+ {0x4873, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid3?" chp.rglid[0];
+ //LID: for non-Far East text
+ //(like a duplicate of 486D)
+ {0x4874, 0}, //undocumented
+ {0x6463, 0}, //undocumented
+ {0x2461, &SwWW8ImplReader::Read_RTLJustify}, //undoc, must be asian version
+ //of "sprmPJc"
+ {0x845E, &SwWW8ImplReader::Read_LR}, //Apparently post-Word 97 version of "sprmPDxaLeft"
+ {0x8460, &SwWW8ImplReader::Read_LR}, //Post-Word 97 version of "sprmPDxaLeft1"
+ {0x845D, &SwWW8ImplReader::Read_LR}, //Post-Word 97 version of "sprmPDxaRight"
+ {0x3615, 0}, //undocumented
+ {0x360D, 0}, //undocumented
+ {0x940E, 0}, //undocumented
+ {0x940F, 0}, //undocumented
+ {0x9410, 0}, //undocumented
+ {0x703A, 0}, //undocumented
+ {0x303B, 0}, //undocumented
+ {0x244B, &SwWW8ImplReader::Read_TabCellEnd}, //undocumented, must be
+ //subtable "sprmPFInTable"
+ {0x244C, &SwWW8ImplReader::Read_TabRowEnd}, //undocumented, must be
+ // subtable "sprmPFTtp"
+ {0x6815, 0}, //undocumented
+ {0x6816, 0}, //undocumented
+ {0x6870, &SwWW8ImplReader::Read_TxtForeColor},
+ {0xC64D, &SwWW8ImplReader::Read_ParaBackColor},
+ {0x6467, 0}, //undocumented
+ {0xF617, 0}, //undocumented
+ {0xD660, 0}, //undocumented
+ {0xD670, 0}, //undocumented
+ {0xCA71, &SwWW8ImplReader::Read_TxtBackColor},//undocumented
+ {0x303C, 0}, //undocumented
+ {0x245B, &SwWW8ImplReader::Read_ParaAutoBefore},//undocumented, para
+ {0x245C, &SwWW8ImplReader::Read_ParaAutoAfter},//undocumented, para
+ {0x246D, &SwWW8ImplReader::Read_DontAddEqual}//undocumented, para
+ };
+
+ static wwSprmDispatcher aSprmSrch(aSprms, sizeof(aSprms) / sizeof(aSprms[0]));
+ return &aSprmSrch;
+}
+
+//-----------------------------------------
+// Hilfsroutinen : SPRM finden
+//-----------------------------------------
+
+const SprmReadInfo& SwWW8ImplReader::GetSprmReadInfo(USHORT nId) const
+{
+ ww::WordVersion eVersion = pWwFib->GetFIBVersion();
+ const wwSprmDispatcher *pDispatcher;
+ if (eVersion <= ww::eWW2)
+ pDispatcher = GetWW2SprmDispatcher();
+ else if (eVersion < ww::eWW8)
+ pDispatcher = GetWW6SprmDispatcher();
+ else
+ pDispatcher = GetWW8SprmDispatcher();
+
+ SprmReadInfo aSrch = {0, 0};
+ aSrch.nId = nId;
+ const SprmReadInfo* pFound = pDispatcher->search(aSrch);
+
+ if (!pFound)
+ {
+ aSrch.nId = 0;
+ pFound = pDispatcher->search(aSrch);
+ }
+
+ return *pFound;
+}
+
+//-----------------------------------------
+// Hilfsroutinen : SPRMs
+//-----------------------------------------
+void SwWW8ImplReader::EndSprm( USHORT nId )
+{
+ if( ( nId > 255 ) && ( nId < 0x0800 ) ) return;
+
+ const SprmReadInfo& rSprm = GetSprmReadInfo( nId );
+
+ if (rSprm.pReadFnc)
+ (this->*rSprm.pReadFnc)( nId, 0, -1 );
+}
+
+short SwWW8ImplReader::ImportSprm(const BYTE* pPos,USHORT nId)
+{
+ if (!nId)
+ nId = mpSprmParser->GetSprmId(pPos);
+
+#if OSL_DEBUG_LEVEL > 1
+ ASSERT( nId != 0xff, "Sprm FF !!!!" );
+#endif
+
+ const SprmReadInfo& rSprm = GetSprmReadInfo(nId);
+
+ USHORT nFixedLen = mpSprmParser->DistanceToData(nId);
+ USHORT nL = mpSprmParser->GetSprmSize(nId, pPos);
+
+ if (rSprm.pReadFnc)
+ (this->*rSprm.pReadFnc)(nId, pPos + nFixedLen, nL - nFixedLen);
+
+ return nL;
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */