blob: b3fa09df82aaa48c58a686d3617f088de394e70d [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the 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
sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap,
const WW8RStyle* pSty = 0, const WW8PLCFx_SEPX* pSep = 0);
ColorData SwWW8ImplReader::GetCol(sal_uInt8 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, sal_uInt16 nId, short nDefaultVal )
{
const sal_uInt8* pS = pSep->HasSprm( nId ); // sprm da ?
short nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
return nVal;
}
static sal_uInt16 ReadUSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, short nDefaultVal )
{
const sal_uInt8* pS = pSep->HasSprm( nId ); // sprm da ?
sal_uInt16 nVal = ( pS ) ? SVBT16ToShort( pS ) : nDefaultVal;
return nVal;
}
static sal_uInt8 ReadBSprm( const WW8PLCFx_SEPX* pSep, sal_uInt16 nId, sal_uInt8 nDefaultVal )
{
const sal_uInt8* pS = pSep->HasSprm( nId ); // sprm da ?
sal_uInt8 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();
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 );
if ( eType != GRID_NONE )
{
//sep.dyaLinePitch
const sal_Int32 nLinePitch = rSection.maSep.dyaLinePitch;
//Get the size of word's default styles font
sal_uInt32 nCharWidth=240;
for (sal_uInt16 nI = 0; nI < pStyles->GetCount(); ++nI)
{
if (pCollA[nI].bValid
&& pCollA[nI].pFmt != NULL
&& pCollA[nI].IsWW8BuiltInDefaultStyle())
{
nCharWidth = ItemGet<SvxFontHeightItem>(*(pCollA[nI].pFmt),
RES_CHRATR_CJK_FONTSIZE).GetHeight();
break;
}
}
//dxtCharSpace
if (rSection.maSep.dxtCharSpace)
{
sal_uInt32 nCharSpace = rSection.maSep.dxtCharSpace;
//main lives in top 20 bits, and is signed.
sal_Int32 nMain = (nCharSpace & 0xFFFFF000);
nMain/=0x1000;
nCharWidth += nMain*20;
int nFraction = (nCharSpace & 0x00000FFF);
nFraction = (nFraction*20)/0xFFF;
nCharWidth += nFraction;
}
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);
}
// only apply sensible grid property values
if ( nLinePitch > 0
&& nCharWidth > 0
&& nTextareaHeight > nLinePitch )
{
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(sal_uInt16, const sal_uInt8* 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<sal_uInt16>(nColSpace),
writer_cast<sal_uInt16>(nNettoWidth));
// sprmSFEvenlySpaced
if (!rSection.maSep.fEvenlySpaced)
{
aCol._SetOrtho(false);
int nIdx = 1;
for (sal_uInt16 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<sal_uInt16>(nWishWidth));
pCol->SetLeft(writer_cast<sal_uInt16>(nLeft));
pCol->SetRight(writer_cast<sal_uInt16>(nRight));
nIdx += 2;
}
aCol.SetWishWidth(writer_cast<sal_uInt16>(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());
}
sal_uInt16 lcl_MakeSafeNegativeSpacing(sal_uInt16 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)
{
sal_uInt16 nDist;
if (aBox.GetLeft())
{
nDist = aBox.GetDistance(BOX_LINE_LEFT);
aBox.SetDistance(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(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<sal_uInt16>(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<sal_uInt16>(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<sal_uInt16>(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<sal_uInt16>(aLR.GetLeft() - aSizeArray[WW8_LEFT])));
if (aBox.GetRight())
aLR.SetRight(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(aLR.GetRight() - aSizeArray[WW8_RIGHT])));
if (aBox.GetTop())
aUL.SetUpper(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(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<sal_uInt16>(aUL.GetLower() - aSizeArray[WW8_BOT])));
else
aUL.SetLower(lcl_MakeSafeNegativeSpacing(static_cast<sal_uInt16>(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<sal_uInt16>(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< sal_uInt16 >(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<sal_uInt16>(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< sal_uInt16 >(nFtUpperSpace) );
// <--
pFtFmt->SetFmtAttr(SwHeaderAndFooterEatSpacingItem(
RES_HEADER_FOOTER_EAT_SPACING, false));
}
pFtFmt->SetFmtAttr(aFtUL);
}
}
SvxULSpaceItem aUL(writer_cast<sal_uInt16>(rData.nSwUp),
writer_cast<sal_uInt16>(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<sal_uInt16>(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
sal_uInt16 nLIdx = ( ( mrReader.pWwFib->lid & 0xff ) == 0x9 ) ? 1 : 0;
//BEGIN read section values
wwSection aNewSection(*mrReader.pPaM->GetPoint());
static const sal_uInt16 aVer2Ids0[] =
{
/*sprmSBkc*/ 117,
/*sprmSFTitlePage*/ 118,
/*sprmSNfcPgn*/ 122,
/*sprmSCcolumns*/ 119,
/*sprmSDxaColumns*/ 120,
/*sprmSLBetween*/ 133
};
static const sal_uInt16 aVer67Ids0[] =
{
/*sprmSBkc*/ 142,
/*sprmSFTitlePage*/ 143,
/*sprmSNfcPgn*/ 147,
/*sprmSCcolumns*/ 144,
/*sprmSDxaColumns*/ 145,
/*sprmSLBetween*/ 158
};
static const sal_uInt16 aVer8Ids0[] =
{
/*sprmSBkc*/ 0x3009,
/*sprmSFTitlePage*/ 0x300A,
/*sprmSNfcPgn*/ 0x300E,
/*sprmSCcolumns*/ 0x500B,
/*sprmSDxaColumns*/ 0x900C,
/*sprmSLBetween*/ 0x3019
};
const sal_uInt16* 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 sal_uInt8* 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;
// Reading section property sprmSCcolumns - one less than the number of columns in the section.
// It must be less than MAX_NO_OF_SEP_COLUMNS according the WW8 specification.
aNewSection.maSep.ccolM1 = ReadSprm(pSep, pIds[3], 0 );
if ( aNewSection.maSep.ccolM1 >= MAX_NO_OF_SEP_COLUMNS )
{
// fallback to one column
aNewSection.maSep.ccolM1 = 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 )
{
int nColumnDataIdx = 0;
aNewSection.maSep.rgdxaColumnWidthSpacing[nColumnDataIdx] = 0;
const sal_uInt16 nColumnWidthSprmId = ( eVer <= ww::eWW7 ? 136 : 0xF203 );
const sal_uInt16 nColumnSpacingSprmId = ( eVer <= ww::eWW7 ? 137 : 0xF204 );
const sal_uInt8 nColumnCount = static_cast< sal_uInt8 >(aNewSection.maSep.ccolM1 + 1);
for ( sal_uInt8 nColumn = 0; nColumn < nColumnCount; ++nColumn )
{
//sprmSDxaColWidth
const sal_uInt8* pSW = pSep->HasSprm( nColumnWidthSprmId, nColumn );
ASSERT( pSW != NULL, "+Sprm 136 (bzw. 0xF203) (ColWidth) fehlt" );
sal_uInt16 nWidth = pSW != NULL ? SVBT16ToShort( pSW + 1 ) : 1440;
aNewSection.maSep.rgdxaColumnWidthSpacing[++nColumnDataIdx] = nWidth;
if ( nColumn < nColumnCount - 1 )
{
//sprmSDxaColSpacing
const sal_uInt8* pSD = pSep->HasSprm( nColumnSpacingSprmId, nColumn );
ASSERT( pSD, "+Sprm 137 (bzw. 0xF204) (Colspacing) fehlt" );
if ( pSD )
{
nWidth = SVBT16ToShort( pSD + 1 );
aNewSection.maSep.rgdxaColumnWidthSpacing[++nColumnDataIdx] = nWidth;
}
}
}
}
}
static const sal_uInt16 aVer2Ids1[] =
{
/*sprmSBOrientation*/ 137,
/*sprmSXaPage*/ 139,
/*sprmSYaPage*/ 140,
/*sprmSDxaLeft*/ 141,
/*sprmSDxaRight*/ 142,
/*sprmSDzaGutter*/ 145,
/*sprmSFPgnRestart*/ 125,
/*sprmSPgnStart*/ 136,
/*sprmSDmBinFirst*/ 115,
/*sprmSDmBinOther*/ 116
};
static const sal_uInt16 aVer67Ids1[] =
{
/*sprmSBOrientation*/ 162,
/*sprmSXaPage*/ 164,
/*sprmSYaPage*/ 165,
/*sprmSDxaLeft*/ 166,
/*sprmSDxaRight*/ 167,
/*sprmSDzaGutter*/ 170,
/*sprmSFPgnRestart*/ 150,
/*sprmSPgnStart*/ 161,
/*sprmSDmBinFirst*/ 140,
/*sprmSDmBinOther*/ 141
};
static const sal_uInt16 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 sal_uInt16 nLef[] = { MM_250, 1800 };
static const sal_uInt16 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 sal_uInt8* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 132 : 0x3001) ))
aNewSection.maSep.iHeadingPgn = *p;
if (const sal_uInt8* p = pSep->HasSprm( (eVer <= ww::eWW7 ? 131 : 0x3000) ))
aNewSection.maSep.cnsPgn = *p;
}
if(const sal_uInt8* pSprmSDmBinFirst = pSep->HasSprm( pIds[8] ))
aNewSection.maSep.dmBinFirst = *pSprmSDmBinFirst;
if (const sal_uInt8* pSprmSDmBinOther = pSep->HasSprm( pIds[9] ))
aNewSection.maSep.dmBinOther = *pSprmSDmBinOther;
static const sal_uInt16 nTop[] = { MM_250, 1440 };
static const sal_uInt16 nBot[] = { MM_200, 1440 };
static const sal_uInt16 aVer2Ids2[] =
{
/*sprmSDyaTop*/ 143,
/*sprmSDyaBottom*/ 144,
/*sprmSDyaHdrTop*/ 131,
/*sprmSDyaHdrBottom*/ 132,
/*sprmSNLnnMod*/ 129,
/*sprmSLnc*/ 127,
/*sprmSDxaLnn*/ 130,
/*sprmSLnnMin*/ 135
};
static const sal_uInt16 aVer67Ids2[] =
{
/*sprmSDyaTop*/ 168,
/*sprmSDyaBottom*/ 169,
/*sprmSDyaHdrTop*/ 156,
/*sprmSDyaHdrBottom*/ 157,
/*sprmSNLnnMod*/ 154,
/*sprmSLnc*/ 152,
/*sprmSDxaLnn*/ 155,
/*sprmSLnnMin*/ 160
};
static const sal_uInt16 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 sal_uInt8* 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 sal_uInt8* pSprmSNLnnMod = pSep->HasSprm( pIds[4] ))
aNewSection.maSep.nLnnMod = *pSprmSNLnnMod;
if (const sal_uInt8* pSprmSLnc = pSep->HasSprm( pIds[5] ))
aNewSection.maSep.lnc = *pSprmSLnc;
if (const sal_uInt8* pSprmSDxaLnn = pSep->HasSprm( pIds[6] ))
aNewSection.maSep.dxaLnn = SVBT16ToShort( pSprmSDxaLnn );
if (const sal_uInt8* 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, sal_uInt8 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 sal_uInt8* pS)
{
if( pS )
{
if( bVer67 )
memcpy( rVar.aBits1, pS, sizeof( SVBT16 ) );
else
rVar = *((WW8_BRC*)pS);
}
return 0 != pS;
}
sal_uInt8 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 sal_uInt8 filled with a bit for each position that had a sprm
//setting that border
sal_uInt8 nBorder = false;
if( pSep )
{
if( !bVer67 )
{
sal_uInt8* 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 sal_uInt16 aVer67Ids[5] = { 38, 39, 40, 41, 42 };
static const sal_uInt16 aVer8Ids[5] =
{ 0x6424, 0x6425, 0x6426, 0x6427, 0x6428 };
const sal_uInt16* 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, sal_uInt8 nCol, short nIdx,
sal_uInt16 nOOIndex, sal_uInt16 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 < 45) //Modified for i120716
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,
sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize=0)
{
sal_uInt8 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, sal_uInt8 nSetBorders) const
{
bool bChange = false;
static const sal_uInt16 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));
//i120718
short nVal = pbrc[WW8_RIGHT].DetermineBorderProperties(bVer67);
//End
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)
{
const short nMin = MINFLY +
(bBorder ? MAX_BORDER_SIZE : MAX_EMPTY_BORDER);
if ( rSize < nMin )
rSize = nMin;
}
inline bool SetValSprm( sal_Int16* pVar, WW8PLCFx_Cp_FKP* pPap, sal_uInt16 nId )
{
const sal_uInt8* pS = pPap->HasSprm( nId );
if( pS )
*pVar = (sal_Int16)SVBT16ToShort( pS );
return ( pS != 0 );
}
inline bool SetValSprm( sal_Int16* pVar, const WW8RStyle* pStyle, sal_uInt16 nId )
{
const sal_uInt8* pS = pStyle->HasParaSprm( nId );
if( pS )
*pVar = (sal_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 sal_uInt8* pSprm29, WW8PLCFx_Cp_FKP* pPap)
{
if (pSprm29)
nOrigSp29 = *pSprm29; // PPC ( Bindung )
const sal_uInt8* 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 sal_uInt8* 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;
sal_uLong nPos = pIoStrm->Tell();
WW8PLCFxSave1 aSave;
pPlcxMan->GetPap()->Save( aSave );
bGrafApo = false;
do{ // Block zum rausspringen
sal_uInt8 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 sal_uInt8* 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;
sal_uInt16 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 sal_uInt8* pSprm29, WW8RStyle* pStyle)
{
if (pSprm29)
nOrigSp29 = *pSprm29; // PPC ( Bindung )
const sal_uInt8* 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 sal_Int32 nIniFlyDx,
const sal_Int32 nIniFlyDy )
{
(void) rPaM;
(void) nPgLeft;
memset( this, 0, sizeof( WW8SwFlyPara ) ); // Initialisieren
nNewNettoWidth = MINFLY; // Minimum
eSurround = ( rWW.nSp37 > 1 ) ? SURROUND_IDEAL : SURROUND_NONE;
//#i119466 mapping "Around" wrap setting to "Parallel" for table
const bool bIsTable = rIo.pPlcxMan->HasParaSprm(0x2416);
if ( bIsTable && rWW.nSp37 == 2 )
eSurround = SURROUND_PARALLEL;
/*
#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
sal_Int16 nLeBorderMgn( 0L );
if ( !bAutoWidth )
{
sal_Int16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67,
&nLeBorderMgn);
nLeBorderMgn = nLeBorderMgn + nTemp;
}
// determine right border distance
sal_Int16 nRiBorderMgn( 0L );
if ( !bAutoWidth )
{
sal_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
*/
sal_Int16 nLeLMgn = 0;
sal_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< sal_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
sal_uInt16 nCnt = static_cast< sal_uInt16 >(pCtrlStck->Count());
for (sal_uInt16 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 sal_uInt8 *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( sal_uInt16 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(sal_uInt16, const sal_uInt8* 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(sal_uInt16 , const sal_uInt8* pData, short nLen)
{
if( nLen < 0 )
bObj = false;
else
{
bObj = 0 != *pData;
if( bObj && nPicLocFc && bEmbeddObj )
nObjLocFc = nPicLocFc;
}
}
void SwWW8ImplReader::Read_PicLoc(sal_uInt16 , const sal_uInt8* 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(sal_uInt16, const sal_uInt8* pData, short nLen )
{
if ( nLen < 0 )
{
pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_OUTLINELEVEL );
return;
}
if ( pAktColl != NULL )
{
SwWW8StyInf* pSI = GetStyle( nAktColl );
if ( pSI != NULL )
{
pSI->mnWW8OutlineLevel =
static_cast< sal_uInt8 >( ( pData ? *pData : 0 ) );
NewAttr( SfxUInt16Item( RES_PARATR_OUTLINELEVEL, SwWW8StyInf::WW8OutlineLevelToOutlinelevel( pSI->mnWW8OutlineLevel ) ) );
}
}
else if ( pPaM != NULL )
{
const sal_uInt8 nOutlineLevel =
SwWW8StyInf::WW8OutlineLevelToOutlinelevel( static_cast< sal_uInt8 >( ( pData ? *pData : 0 ) ) );
NewAttr( SfxUInt16Item( RES_PARATR_OUTLINELEVEL, nOutlineLevel ) );
}
}
void SwWW8ImplReader::Read_Symbol(sal_uInt16, const sal_uInt8* 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(sal_uInt16 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( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
{
const int nContigiousWestern = 8;
const int nWestern = nContigiousWestern + 1;
const int nEastern = 2;
const int nIds = nWestern + nEastern;
static const sal_uInt16 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();
sal_uInt8 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< sal_uInt8 >(nId - 60);
else if (eVersion < ww::eWW8)
nI = static_cast< sal_uInt8 >(nId - 85);
else
nI = static_cast< sal_uInt8 >(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 sal_uInt8 *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(sal_uInt16, const sal_uInt8* pData, short nLen)
{
if( nLen < 0 ) //Property end
{
bBidi = sal_False;
pCtrlStck->SetAttr(*pPaM->GetPoint(),RES_CHRATR_BIDIRTL);
}
else //Property start
{
bBidi = sal_True;
sal_uInt8 nBidi = SVBT8ToByte( pData );
NewAttr( SfxInt16Item( RES_CHRATR_BIDIRTL, (nBidi!=0)? 1 : 0 ) );
}
}
// Read_BoldUsw for BiDi Italic, Bold
void SwWW8ImplReader::Read_BoldBiDiUsw(sal_uInt16 nId, const sal_uInt8* pData,
short nLen)
{
static const sal_uInt16 nEndIds[2] =
{
RES_CHRATR_CTL_WEIGHT, RES_CHRATR_CTL_POSTURE,
};
sal_uInt8 nI;
ww::WordVersion eVersion = pWwFib->GetFIBVersion();
if (eVersion <= ww::eWW2)
nI = static_cast< sal_uInt8 >(nId - 80);
else if (eVersion < ww::eWW8)
nI = static_cast< sal_uInt8 >(nId - 111);
else
nI = static_cast< sal_uInt8 >(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 sal_uInt8 *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(sal_uInt8 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(sal_uInt8 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( sal_uInt16 nOldStyle81Mask,
sal_uInt16 nNewStyle81Mask )
{
sal_uInt16 i = 1, nToggleAttrFlags = pCtrlStck->GetToggleAttrFlags();
for (sal_uInt8 n = 0; n < 7; ++n, i <<= 1)
{
if (
(i & nToggleAttrFlags) &&
((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
)
{
SetToggleAttr(n, (i & nOldStyle81Mask));
}
}
}
void SwWW8ImplReader::_ChkToggleBiDiAttr( sal_uInt16 nOldStyle81Mask,
sal_uInt16 nNewStyle81Mask )
{
sal_uInt16 i = 1, nToggleAttrFlags = pCtrlStck->GetToggleBiDiAttrFlags();
for (sal_uInt8 n = 0; n < 7; ++n, i <<= 1)
{
if (
(i & nToggleAttrFlags) &&
((i & nOldStyle81Mask) != (i & nNewStyle81Mask))
)
{
SetToggleBiDiAttr(n, (i & nOldStyle81Mask));
}
}
}
void SwWW8ImplReader::Read_SubSuper( sal_uInt16, const sal_uInt8* pData, short nLen )
{
if( nLen < 0 ){
pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_ESCAPEMENT );
return;
}
short nEs;
sal_uInt8 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;
sal_uInt16 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( sal_uInt16, const sal_uInt8* 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 );
sal_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.
sal_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( sal_uInt16, const sal_uInt8* 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 )
{
sal_uInt8 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( sal_uInt16, const sal_uInt8* 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( sal_uInt16, const sal_uInt8* 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
{
sal_uInt8 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(sal_uInt16, const sal_uInt8* 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;
}
}
void SwWW8ImplReader::Read_UnderlineColor(sal_uInt16, const sal_uInt8* pData, short nLen)
{
if( nLen < 0 )
{
//because the UnderlineColor is not a standalone attribute in SW, it belongs to the underline attribute.
//And, the .doc file stores attributes separately, this attribute ends here, the "underline"
//attribute also terminates (if the character next owns underline, that will be a new underline attribute).
//so nothing is left to be done here.
return;
}
else
{
if ( pAktColl ) //importing style
{
if( SFX_ITEM_SET == pAktColl->GetItemState( RES_CHRATR_UNDERLINE, sal_False ) )
{
const SwAttrSet& aSet = pAktColl->GetAttrSet();
SvxUnderlineItem *pUnderline
= (SvxUnderlineItem *)(aSet.Get( RES_CHRATR_UNDERLINE, sal_False ).Clone());
if(pUnderline){
pUnderline->SetColor( Color( wwUtility::BGRToRGB(SVBT32ToUInt32(pData)) ) );
pAktColl->SetFmtAttr( *pUnderline );
delete pUnderline;
}
}
}
else if ( pAktItemSet )
{
if ( SFX_ITEM_SET == pAktItemSet->GetItemState( RES_CHRATR_UNDERLINE, sal_False ) )
{
SvxUnderlineItem *pUnderline
= (SvxUnderlineItem *)(pAktItemSet->Get( RES_CHRATR_UNDERLINE, sal_False ) .Clone());
if(pUnderline){
pUnderline->SetColor( Color( wwUtility::BGRToRGB(SVBT32ToUInt32(pData)) ) );
pAktItemSet->Put( *pUnderline );
delete pUnderline;
}
}
}
else
{
SvxUnderlineItem* pUnderlineAttr = (SvxUnderlineItem*)pCtrlStck->GetOpenStackAttr( *pPaM->GetPoint(), RES_CHRATR_UNDERLINE );
if( pUnderlineAttr != NULL )
pUnderlineAttr->SetColor( Color( wwUtility::BGRToRGB(SVBT32ToUInt32( pData ))));
}
}
}
bool SwWW8ImplReader::GetFontParams( sal_uInt16 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
sal_uInt8 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( sal_uInt16 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)/sizeof(eFamilyA[0])))
reFamily = eFamilyA[b];
else
reFamily = FAMILY_DONTKNOW;
return true;
}
sal_uInt16 SwWW8ImplReader::CorrectResIdForCharset(CharSet nCharSet, sal_uInt16 nWhich)
{
sal_uInt16 nResult = 0;
switch (nCharSet) {
case RTL_TEXTENCODING_MS_932:
nResult = RES_CHRATR_CJK_FONT;
break;
default:
nResult = nWhich;
break;
}
return nResult;
}
bool SwWW8ImplReader::SetNewFontAttr(sal_uInt16 nFCode, bool bSetEnums,
sal_uInt16 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( sal_uInt16 nId, const sal_uInt8* pData, short nLen )
{
if (!bSymbol) // falls bSymbol, gilt der am Symbol
{ // (siehe sprmCSymbol) gesetzte Font !
switch( nId )
{
case 113:
case 0x4A51: //"Other" font, override with BiDi if it exists
case 0x4A5E: //BiDi Font
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
{
sal_uInt16 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( sal_uInt16 nId, const sal_uInt8* 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 )
sal_uInt16 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(sal_uInt16 , const sal_uInt8* pData, short nLen)
{
if( nLen < 0 )
{ // Ende des Attributes
eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
return;
}
sal_uInt8 nfChsDiff = SVBT8ToByte( pData );
if( nfChsDiff )
eHardCharSet = rtl_getTextEncodingFromWindowsCharset( *(pData + 1) );
else
eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
}
void SwWW8ImplReader::Read_Language( sal_uInt16 nId, const sal_uInt8* 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
{
sal_uInt16 nLang = SVBT16ToShort( pData ); // Language-Id
NewAttr(SvxLanguageItem((const LanguageType)nLang, nId));
}
}
/*
Einschalten des Zeichen-Styles:
*/
void SwWW8ImplReader::Read_CColl( sal_uInt16, const sal_uInt8* pData, short nLen )
{
if( nLen < 0 ){ // Ende des Attributes
pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_TXTATR_CHARFMT );
nCharFmt = -1;
return;
}
sal_uInt16 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
// if current on loading a TOC field, and current trying to apply a hyperlink character style,
// just ignore. For the hyperlinks inside TOC in MS Word is not same with a common hyperlink
// Character styles: without underline and blue font color. And such type style will be applied in others
// processes.
if (mbLoadingTOCCache && pCollA[nId].GetWWStyleId() == ww::stiHyperlink)
{
return;
}
NewAttr( SwFmtCharFmt( (SwCharFmt*)pCollA[nId].pFmt ) );
nCharFmt = (short) nId;
}
/*
enger oder weiter als normal:
*/
void SwWW8ImplReader::Read_Kern( sal_uInt16, const sal_uInt8* pData, short nLen )
{
if( nLen < 0 ){ // Ende des Attributes
pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_KERNING );
return;
}
sal_Int16 nKern = SVBT16ToShort( pData ); // Kerning in Twips
NewAttr( SvxKerningItem( nKern, RES_CHRATR_KERNING ) );
}
void SwWW8ImplReader::Read_FontKern( sal_uInt16, const sal_uInt8* , 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( sal_uInt16, const sal_uInt8* 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(sal_uInt16, const sal_uInt8* 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(sal_uInt16, const sal_uInt8* 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
{
sal_uInt8 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(sal_uInt16 , const sal_uInt8* 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 );
}
bool lcl_HasExplicitLeft(const WW8PLCFMan *pPlcxMan, bool bVer67)
{
WW8PLCFx_Cp_FKP *pPap = pPlcxMan ? pPlcxMan->GetPapPLCF() : 0;
if (pPap)
{
if (bVer67)
return pPap->HasSprm(17);
else
return (pPap->HasSprm(0x840F) || pPap->HasSprm(0x845E));
}
return false;
}
// Sprm 16, 17
void SwWW8ImplReader::Read_LR( sal_uInt16 nId, const sal_uInt8* 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 sal_uInt8 *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)
{
if (const SwTxtNode* pNode = pPaM->GetNode()->GetTxtNode())
{
if ( const SwNumFmt *pNumFmt = GetNumFmtFromTxtNode(*pNode) )
{
if (!lcl_HasExplicitLeft(pPlcxMan, bVer67))
{
aLR.SetTxtLeft(pNumFmt->GetIndentAt());
// If have not explicit left, set number format list tab position is doc default tab
const SvxTabStopItem *pDefaultStopItem = (const SvxTabStopItem *)rDoc.GetAttrPool().GetPoolDefaultItem(RES_PARATR_TABSTOP);
if ( pDefaultStopItem && pDefaultStopItem->Count() > 0 )
((SwNumFmt*)(pNumFmt))->SetListtabPos( ((SvxTabStop&)(*pDefaultStopItem)[0]).GetTabPos() );
}
}
}
}
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( sal_uInt16, const sal_uInt8* 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"
sal_uInt16 nWwPre = 0;
sal_uInt16 nWwPost = 0;
sal_uInt16 nSwPre = 0;
sal_uInt16 nSwPost = 0;
sal_uInt16 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 sal_uInt8)n );
const SvxFontHeightItem* pH = (const SvxFontHeightItem*)
GetFmtAttr( RES_CHRATR_FONTSIZE );
nSpaceTw = (sal_uInt16)( n * pH->GetHeight() / 100 );
if( n > 100 )
nWwPost = nSwPre = nSwPost = (sal_uInt16)( ( n - 100 )
* pH->GetHeight() / 100 );
}
else // Fixed / Minimum
{
// bei negativen Space ist der Abstand exakt, sonst minimum
nSpaceTw = (sal_uInt16)nSpace;
aLSpc.SetLineHeight( nSpaceTw );
aLSpc.GetLineSpaceRule() = eLnSpc;
nSwPre = nSpace;
if( SVX_LINE_SPACE_FIX == eLnSpc ) // Genau
{
nWwPre = (sal_uInt16)( 8L * nSpace / 10 );
nWwPost = (sal_uInt16)( 2L * nSpace / 10 );
nSwPre = nSpace;
}
else // Minimum
{
nWwPre = (sal_uInt16)( 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(sal_uInt16, const sal_uInt8 *pData, short nLen)
{
if (nLen < 0)
return;
if (*pData)
maTracer.Log(sw::log::eDontAddSpaceForEqualStyles);
}
void SwWW8ImplReader::Read_ParaAutoBefore(sal_uInt16, const sal_uInt8 *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(sal_uInt16, const sal_uInt8 *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( sal_uInt16 nId, const sal_uInt8* 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( sal_uInt16, const sal_uInt8* pData, short nLen )
{
// sprmcidcthint (opcode 0x286f) specifies a script bias for the text in the run.
// for unicode characters that are shared between far east and non-far east scripts,
// this property determines what font and language the character will use.
// when this value is 0, text properties bias towards non-far east properties.
// when this value is 1, text properties bias towards far east properties.
if( nLen < 0 ) //Property end
{
pCtrlStck->SetAttr(*pPaM->GetPoint(),RES_CHRATR_IDCTHINT);
}
else //Property start
{
sal_uInt8 nVal = SVBT8ToByte( pData );
NewAttr( SfxInt16Item( RES_CHRATR_IDCTHINT, (nVal!=0)? 1 : 0 ) );
}
}
void SwWW8ImplReader::Read_Justify( sal_uInt16, const sal_uInt8* 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 sal_uInt8 *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( sal_uInt16, const sal_uInt8* 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( sal_uInt16 nId, const sal_uInt8* 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( sal_uInt16, const sal_uInt8* 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 sal_uInt8 *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( sal_uInt16, const sal_uInt8* 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( sal_uInt16 nId, const sal_uInt8* 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(sal_uInt16 /*nId*/, const sal_uInt8* 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)
{
sal_uInt8 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 sal_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;
sal_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( sal_uInt16, const sal_uInt8* 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(sal_uInt16, const sal_uInt8* 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 sal_uInt8* &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(sal_uInt16 , const sal_uInt8* , 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
sal_uInt8 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( (sal_uInt16)aInnerDist.Left(), BOX_LINE_LEFT );
aBox.SetDistance( (sal_uInt16)aInnerDist.Top(), BOX_LINE_TOP );
aBox.SetDistance( (sal_uInt16)aInnerDist.Right(), BOX_LINE_RIGHT );
aBox.SetDistance( (sal_uInt16)aInnerDist.Bottom(), BOX_LINE_BOTTOM );
NewAttr( aBox );
SvxShadowItem aS(RES_SHADOW);
if( SetShadow( aS, &aSizeArray[0], aBrcs ) )
NewAttr( aS );
}
}
}
}
void SwWW8ImplReader::Read_Hyphenation( sal_uInt16, const sal_uInt8* 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( sal_uInt16, const sal_uInt8* pData, short nLen )
{
if( nLen <= 0 )
{
pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_WIDOWS );
pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_ORPHANS );
}
else
{
sal_uInt8 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(sal_uInt16,const sal_uInt8* 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( sal_uInt16, const sal_uInt8* 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( sal_uInt16, const sal_uInt8* 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( sal_uInt16, const sal_uInt8* pData, short nLen )
{
if( nLen <= 0 )
pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_KEEP );
else
NewAttr( SvxFmtKeepItem( ( *pData & 1 ) != 0 , RES_KEEP) );
}
void SwWW8ImplReader::Read_BreakBefore( sal_uInt16, const sal_uInt8* 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( sal_uInt16, const sal_uInt8* 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 sal_uInt8 *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 )
{
sal_uInt8 nIdx = static_cast< sal_uInt8 >(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(sal_uInt16 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
};
sal_uInt8 nIdx = static_cast< sal_uInt8 >(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)( sal_uInt16, const sal_uInt8*, short );
struct SprmReadInfo
{
sal_uInt16 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}, //"sprmCFtcBi"
{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},
{0x6877, &SwWW8ImplReader::Read_UnderlineColor},
{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(sal_uInt16 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( sal_uInt16 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 sal_uInt8* pPos,sal_uInt16 nId)
{
if (!nId)
nId = mpSprmParser->GetSprmId(pPos);
#if OSL_DEBUG_LEVEL > 1
ASSERT( nId != 0xff, "Sprm FF !!!!" );
#endif
const SprmReadInfo& rSprm = GetSprmReadInfo(nId);
sal_uInt16 nFixedLen = mpSprmParser->DistanceToData(nId);
sal_uInt16 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: */