diff options
Diffstat (limited to 'sw/source')
-rw-r--r-- | sw/source/filter/ww8/wrtww8.hxx | 5 | ||||
-rw-r--r-- | sw/source/filter/ww8/wrtww8gr.cxx | 12 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8atr.cxx | 118 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par.hxx | 22 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par2.cxx | 182 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8par6.cxx | 229 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8scan.cxx | 198 | ||||
-rw-r--r-- | sw/source/filter/ww8/ww8struc.hxx | 135 |
8 files changed, 496 insertions, 405 deletions
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx index 883d1e34bf5f..21101e9c5b45 100644 --- a/sw/source/filter/ww8/wrtww8.hxx +++ b/sw/source/filter/ww8/wrtww8.hxx @@ -1082,13 +1082,14 @@ public: const SwPageDesc* pNewPgDesc = 0 ); void Out_BorderLine(ww::bytes& rO, const ::editeng::SvxBorderLine* pLine, - sal_uInt16 nDist, sal_uInt16 nSprmNo, bool bShadow); + sal_uInt16 nDist, sal_uInt16 nSprmNo, sal_uInt16 nSprmNoVer9, + bool bShadow); void Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow); void Out_SwFmtTableBox( ww::bytes& rO, const SvxBoxItem * rBox ); sal_uInt8 TransCol( const Color& rCol ); bool TransBrush(const Color& rCol, WW8_SHD& rShd); - WW8_BRC TranslateBorderLine(const ::editeng::SvxBorderLine& pLine, + WW8_BRCVer9 TranslateBorderLine(const ::editeng::SvxBorderLine& pLine, sal_uInt16 nDist, bool bShadow); // #i77805# - new return value indicates, if an inherited outline numbering is suppressed diff --git a/sw/source/filter/ww8/wrtww8gr.cxx b/sw/source/filter/ww8/wrtww8gr.cxx index 7e59a05d9bcd..a1c2d1124a35 100644 --- a/sw/source/filter/ww8/wrtww8gr.cxx +++ b/sw/source/filter/ww8/wrtww8gr.cxx @@ -582,15 +582,18 @@ void SwWW8WrGrf::WritePICFHeader(SvStream& rStrm, const sw::Frame &rFly, WW8_BRC aBrc; if (pLn) { - aBrc = rWrt.TranslateBorderLine( *pLn, + WW8_BRCVer9 aBrc90 = rWrt.TranslateBorderLine( *pLn, pBox->GetDistance( aLnArr[ i ] ), bShadow ); + sal_uInt8 ico = rWrt.TransCol(msfilter::util::BGRToRGB( + aBrc90.cv())); + aBrc = WW8_BRC(ico, aBrc90.dptLineWidth(), aBrc90.brcType(), + aBrc90.dptSpace(), aBrc90.fShadow(), aBrc90.fFrame()); } // use importer logic to determine how large the exported // border will really be in word and adjust accordingly short nSpacing; - short nThick = aBrc.DetermineBorderProperties(!bWrtWW8, - &nSpacing); + short nThick = aBrc.DetermineBorderProperties(&nSpacing); switch (aLnArr[ i ]) { case BOX_LINE_TOP: @@ -778,8 +781,7 @@ void SwWW8WrGrf::WritePICBulletFHeader(SvStream& rStrm, const Graphic &rGrf, WW8_BRC aBrc; short nSpacing; - short nThick = aBrc.DetermineBorderProperties(!bWrtWW8, - &nSpacing); + short nThick = aBrc.DetermineBorderProperties(&nSpacing); switch (aLnArr[ i ]) { case BOX_LINE_TOP: diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx index ddb30bd80ff3..ea149f0651d0 100644 --- a/sw/source/filter/ww8/ww8atr.cxx +++ b/sw/source/filter/ww8/ww8atr.cxx @@ -1229,7 +1229,7 @@ void WW8AttributeOutput::CharHidden( const SvxCharHiddenItem& rHidden ) void WW8AttributeOutput::CharBorder( const SvxBorderLine* pAllBorder, const sal_uInt16 /*nDist*/, const bool bShadow ) { - m_rWW8Export.Out_BorderLine( *m_rWW8Export.pO, pAllBorder, 0, NS_sprm::LN_CBrc, bShadow ); + m_rWW8Export.Out_BorderLine( *m_rWW8Export.pO, pAllBorder, 0, NS_sprm::LN_CBrc, NS_sprm::LN_CBorder, bShadow ); } void WW8AttributeOutput::CharUnderline( const SvxUnderlineItem& rUnderline ) @@ -4169,16 +4169,16 @@ void WW8AttributeOutput::FormatFillGradient( const XFillGradientItem& /*rFillGra { } -WW8_BRC WW8Export::TranslateBorderLine(const SvxBorderLine& rLine, +WW8_BRCVer9 WW8Export::TranslateBorderLine(const SvxBorderLine& rLine, sal_uInt16 nDist, bool bShadow) { // M.M. This function writes out border lines to the word format similar to // what SwRTFWriter::OutRTFBorder does in the RTF filter Eventually it // would be nice if all this functionality was in the one place - WW8_BRC aBrc; + sal_uInt32 nColBGR = 0; sal_uInt16 nWidth = ::editeng::ConvertBorderWidthToWord( rLine.GetBorderLineStyle(), rLine.GetWidth()); - sal_uInt8 brcType = 0, nColCode = 0; + sal_uInt8 brcType = 0; if( nWidth ) // Linie ? { @@ -4248,66 +4248,30 @@ WW8_BRC WW8Export::TranslateBorderLine(const SvxBorderLine& rLine, } } - // BRC.dxpLineWidth + // BRC.dptLineWidth if( bThick ) nWidth /= 2; - if( bWrtWW8 ) - { - // Angabe in 8tel Punkten, also durch 2.5, da 1 Punkt = 20 Twips - nWidth = (( nWidth * 8 ) + 10 ) / 20; - if( 0xff < nWidth ) - nWidth = 0xff; - } - else - { - // Angabe in 0.75 pt - nWidth = ( nWidth + 7 ) / 15; - if( nWidth > 5 ) - nWidth = 5; - ::editeng::SvxBorderStyle const eStyle(rLine.GetBorderLineStyle()); - if (table::BorderLineStyle::DOTTED == eStyle) - nWidth = 6; - else if (table::BorderLineStyle::DASHED == eStyle) - nWidth = 7; - } + // convert width from twips (1/20 pt) to eighths of a point + nWidth = (( nWidth * 8 ) + 10 ) / 20; + if( 0xff < nWidth ) + nWidth = 0xff; if( 0 == nWidth ) // ganz duenne Linie nWidth = 1; // nicht weglassen - // BRC.ico - nColCode = TransCol( rLine.GetColor() ); + // BRC.cv + nColBGR = wwUtility::RGBToBGR(rLine.GetColor().GetRGBColor()); } - // BRC.dxpSpace + // BRC.dptSpace sal_uInt16 nLDist = nDist; nLDist /= 20; // Masseinheit : pt if( nLDist > 0x1f ) nLDist = 0x1f; - if( bWrtWW8 ) - { - aBrc.aBits1[0] = sal_uInt8(nWidth); - aBrc.aBits1[1] = brcType; - aBrc.aBits2[0] = nColCode; - aBrc.aBits2[1] = sal_uInt8(nLDist); - - // fShadow, keine weiteren Einstellungen im WW moeglich - if( bShadow ) - aBrc.aBits2[1] |= 0x20; - } - else - { - sal_uInt16 aBits = nWidth + ( brcType << 3 ); - aBits |= (nColCode & 0x1f) << 6; - aBits |= nLDist << 11; - // fShadow, keine weiteren Einstellungen im WW moeglich - if( bShadow ) - aBits |= 0x20; - ShortToSVBT16( aBits, aBrc.aBits1); - } - - return aBrc; + return WW8_BRCVer9(nColBGR, sal_uInt8(nWidth), brcType, sal_uInt8(nLDist), + bShadow, false); } // MakeBorderLine() bekommt einen WW8Bytes* uebergeben, um die Funktion @@ -4315,7 +4279,7 @@ WW8_BRC WW8Export::TranslateBorderLine(const SvxBorderLine& rLine, // Wenn nSprmNo == 0, dann wird der Opcode nicht ausgegeben. // bShadow darf bei Tabellenzellen *nicht* gesetzt sein ! void WW8Export::Out_BorderLine(ww::bytes& rO, const SvxBorderLine* pLine, - sal_uInt16 nDist, sal_uInt16 nSprmNo, bool bShadow) + sal_uInt16 nDist, sal_uInt16 nSprmNo, sal_uInt16 nSprmNoVer9, bool bShadow) { OSL_ENSURE( ( nSprmNo == 0 ) || ( nSprmNo >= 38 && nSprmNo <= 41 ) || @@ -4323,10 +4287,16 @@ void WW8Export::Out_BorderLine(ww::bytes& rO, const SvxBorderLine* pLine, ( nSprmNo >= NS_sprm::LN_SBrcTop && nSprmNo <= NS_sprm::LN_SBrcRight ), "Sprm for border out is of range" ); - WW8_BRC aBrc; + WW8_BRCVer9 aBrcVer9; + WW8_BRC aBrcVer8; - if (pLine) - aBrc = TranslateBorderLine( *pLine, nDist, bShadow ); + if( pLine && pLine->GetBorderLineStyle() != table::BorderLineStyle::NONE ) + { + aBrcVer9 = TranslateBorderLine( *pLine, nDist, bShadow ); + sal_uInt8 ico = TransCol( msfilter::util::BGRToRGB(aBrcVer9.cv()) ); + aBrcVer8 = WW8_BRC( aBrcVer9.dptLineWidth(), aBrcVer9.brcType(), ico, + aBrcVer9.dptSpace(), aBrcVer9.fShadow(), aBrcVer9.fFrame() ); + } if( bWrtWW8 ) { @@ -4334,15 +4304,22 @@ void WW8Export::Out_BorderLine(ww::bytes& rO, const SvxBorderLine* pLine, if ( nSprmNo != 0 ) SwWW8Writer::InsUInt16( rO, nSprmNo ); - rO.insert( rO.end(), aBrc.aBits1, aBrc.aBits1+2 ); - rO.insert( rO.end(), aBrc.aBits2, aBrc.aBits2+2 ); + rO.insert( rO.end(), aBrcVer8.aBits1, aBrcVer8.aBits2+2 ); + + if ( nSprmNoVer9 != 0 ) + { + SwWW8Writer::InsUInt16( rO, nSprmNoVer9 ); + rO.push_back(sizeof(WW8_BRCVer9)); + rO.insert( rO.end(), aBrcVer9.aBits1, aBrcVer9.aBits2+4); + } } else { + WW8_BRCVer6 aBrcVer6(aBrcVer8); // WW95-SprmIds if ( nSprmNo != 0 ) rO.push_back( static_cast<sal_uInt8>( nSprmNo ) ); - rO.insert( rO.end(), aBrc.aBits1, aBrc.aBits1+2 ); + rO.insert( rO.end(), aBrcVer6.aBits1, aBrcVer6.aBits1+2 ); } } @@ -4359,11 +4336,21 @@ void WW8Export::Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow) }; static const sal_uInt16 aPBrc[] = { - NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft, NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight + // WW8 SPRMs + NS_sprm::LN_PBrcTop, NS_sprm::LN_PBrcLeft, + NS_sprm::LN_PBrcBottom, NS_sprm::LN_PBrcRight, + // WW9 SPRMs + NS_sprm::LN_PBorderTop, NS_sprm::LN_PBorderLeft, + NS_sprm::LN_PBorderBottom, NS_sprm::LN_PBorderRight }; static const sal_uInt16 aSBrc[] = { - NS_sprm::LN_SBrcTop, NS_sprm::LN_SBrcLeft, NS_sprm::LN_SBrcBottom, NS_sprm::LN_SBrcRight + // WW8 SPRMs + NS_sprm::LN_SBrcTop, NS_sprm::LN_SBrcLeft, + NS_sprm::LN_SBrcBottom, NS_sprm::LN_SBrcRight, + // WW9 SPRMs + NS_sprm::LN_SBorderTop, NS_sprm::LN_SBorderLeft, + NS_sprm::LN_SBorderBottom, NS_sprm::LN_SBorderRight, }; static const sal_uInt16 aWW6PBrc[] = { @@ -4375,15 +4362,22 @@ void WW8Export::Out_SwFmtBox(const SvxBoxItem& rBox, bool bShadow) { const SvxBorderLine* pLn = rBox.GetLine( *pBrd ); - sal_uInt16 nSprmNo = 0; + sal_uInt16 nSprmNo, nSprmNoVer9 = 0; if ( !bWrtWW8 ) nSprmNo = aWW6PBrc[i]; else if ( bOutPageDescs ) + { nSprmNo = aSBrc[i]; + nSprmNoVer9 = aSBrc[i+4]; + } else + { nSprmNo = aPBrc[i]; + nSprmNoVer9 = aPBrc[i+4]; + } - Out_BorderLine( *pO, pLn, rBox.GetDistance( *pBrd ), nSprmNo, bShadow ); + Out_BorderLine( *pO, pLn, rBox.GetDistance( *pBrd ), nSprmNo, + nSprmNoVer9, bShadow ); } } @@ -4411,7 +4405,7 @@ void WW8Export::Out_SwFmtTableBox( ww::bytes& rO, const SvxBoxItem * pBox ) else pLn = & aBorderLine; - Out_BorderLine(rO, pLn, 0, 0, false); + Out_BorderLine(rO, pLn, 0, 0, 0, false); } } diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx index e25290c8c3bb..a07f083f74da 100644 --- a/sw/source/filter/ww8/ww8par.hxx +++ b/sw/source/filter/ww8/ww8par.hxx @@ -207,7 +207,7 @@ struct WW8FlyPara sal_Int16 nLeMgn, nRiMgn, nUpMgn, nLoMgn; // Raender sal_uInt8 nSp29; // rohe Bindung + Alignment sal_uInt8 nSp37; // Wrap-Mode ( 1 / 2; 0 = no Apo ? ) - WW8_BRC5 brc; // Umrandung Top, Left, Bottom, Right, Between + WW8_BRCVer9_5 brc; // Umrandung Top, Left, Bottom, Right, Between bool bBorderLines; // Umrandungslinien bool bGrafApo; // true: Dieser Rahmen dient allein dazu, die // enthaltene Grafik anders als zeichengebunden @@ -758,7 +758,7 @@ class wwSection public: wwSection(const SwPosition &rPos); SEPr maSep; - WW8_BRC brc[4]; + WW8_BRCVer9 brc[4]; SwNodeIndex maStart; SwSection *mpSection; SwPageDesc *mpPage; @@ -1006,7 +1006,7 @@ struct WW8TabBandDesc short nOverrideValues[MAX_COL + 1][4]; WW8_SHD* pSHDs; sal_uInt32* pNewSHDs; - WW8_BRC aDefBrcs[6]; + WW8_BRCVer9 aDefBrcs[6]; bool bExist[MAX_COL]; // does this cell exist ? sal_uInt8 nTransCell[MAX_COL + 2]; // translation WW-Index -> SW-Index @@ -1022,8 +1022,8 @@ struct WW8TabBandDesc static void setcelldefaults(WW8_TCell *pCells, short nCells); void ReadDef(bool bVer67, const sal_uInt8* pS); void ProcessDirection(const sal_uInt8* pParams); - void ProcessSprmTSetBRC(bool bVer67, const sal_uInt8* pParamsTSetBRC); - void ProcessSprmTTableBorders(bool bVer67, const sal_uInt8* pParams); + void ProcessSprmTSetBRC(int nBrcVer, const sal_uInt8* pParamsTSetBRC); + void ProcessSprmTTableBorders(int nBrcVer, const sal_uInt8* pParams); void ProcessSprmTDxaCol(const sal_uInt8* pParamsTDxaCol); void ProcessSprmTDelete(const sal_uInt8* pParamsTDelete); void ProcessSprmTInsert(const sal_uInt8* pParamsTInsert); @@ -1426,7 +1426,7 @@ private: const SfxPoolItem* GetFmtAttr( sal_uInt16 nWhich ); bool JoinNode(SwPaM &rPam, bool bStealAttr = false); - bool IsBorder(const WW8_BRC* pbrc, bool bChkBtwn = false) const; + bool IsBorder(const WW8_BRCVer9* pbrc, bool bChkBtwn = false) const; //Set closest writer border equivalent into rBox from pbrc, optionally //recording true winword dimensions in pSizeArray. nSetBorders to mark a @@ -1436,14 +1436,14 @@ private: // Note #i20672# we can't properly support between lines so best to ignore // them for now - bool SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc, short *pSizeArray=0, - sal_uInt8 nSetBorders=0xFF) const; - void GetBorderDistance(const WW8_BRC* pbrc, Rectangle& rInnerDist) const; + bool SetBorder(SvxBoxItem& rBox, const WW8_BRCVer9* pbrc, + short *pSizeArray=0, sal_uInt8 nSetBorders=0xFF) const; + void GetBorderDistance(const WW8_BRCVer9* pbrc, Rectangle& rInnerDist) const; sal_uInt16 GetParagraphAutoSpace(bool fDontUseHTMLAutoSpacing); bool SetShadow(SvxShadowItem& rShadow, const short *pSizeArray, - const WW8_BRC& aRightBrc) const; + const WW8_BRCVer9& aRightBrc) const; //returns true is a shadow was set - bool SetFlyBordersShadow(SfxItemSet& rFlySet, const WW8_BRC *pbrc, + bool SetFlyBordersShadow(SfxItemSet& rFlySet, const WW8_BRCVer9 *pbrc, short *SizeArray=0) const; void SetPageBorder(SwFrmFmt &rFmt, const wwSection &rSection) const; diff --git a/sw/source/filter/ww8/ww8par2.cxx b/sw/source/filter/ww8/ww8par2.cxx index 9209ea3d8abd..ca7cdc227725 100644 --- a/sw/source/filter/ww8/ww8par2.cxx +++ b/sw/source/filter/ww8/ww8par2.cxx @@ -1128,21 +1128,21 @@ void WW8TabBandDesc::ReadDef(bool bVer67, const sal_uInt8* pS) sal_uInt8 aBits1 = pTc->aBits1Ver6; pAktTC->bFirstMerged = ( ( aBits1 & 0x01 ) != 0 ); pAktTC->bMerged = ( ( aBits1 & 0x02 ) != 0 ); - memcpy( pAktTC->rgbrc[ WW8_TOP ].aBits1, - pTc->rgbrcVer6[ WW8_TOP ].aBits1, sizeof( SVBT16 ) ); - memcpy( pAktTC->rgbrc[ WW8_LEFT ].aBits1, - pTc->rgbrcVer6[ WW8_LEFT ].aBits1, sizeof( SVBT16 ) ); - memcpy( pAktTC->rgbrc[ WW8_BOT ].aBits1, - pTc->rgbrcVer6[ WW8_BOT ].aBits1, sizeof( SVBT16 ) ); - memcpy( pAktTC->rgbrc[ WW8_RIGHT ].aBits1, - pTc->rgbrcVer6[ WW8_RIGHT ].aBits1, sizeof( SVBT16 ) ); + pAktTC->rgbrc[ WW8_TOP ] + = WW8_BRC( pTc->rgbrcVer6[ WW8_TOP ] ); + pAktTC->rgbrc[ WW8_LEFT ] + = WW8_BRC( pTc->rgbrcVer6[ WW8_LEFT ] ); + pAktTC->rgbrc[ WW8_BOT ] + = WW8_BRC( pTc->rgbrcVer6[ WW8_BOT ] ); + pAktTC->rgbrc[ WW8_RIGHT ] + = WW8_BRC( pTc->rgbrcVer6[ WW8_RIGHT ] ); if( ( pAktTC->bMerged ) && ( i > 0 ) ) { // Cell merged -> remember //bWWMergedVer6[i] = true; - memcpy( pTCs[i-1].rgbrc[ WW8_RIGHT ].aBits1, - pTc->rgbrcVer6[ WW8_RIGHT ].aBits1, sizeof( SVBT16 ) ); + pTCs[i-1].rgbrc[ WW8_RIGHT ] + = WW8_BRC( pTc->rgbrcVer6[ WW8_RIGHT ] ); // apply right border to previous cell // bExist must not be set to false, because WW // does not count this cells in text boxes.... @@ -1167,8 +1167,10 @@ void WW8TabBandDesc::ReadDef(bool bVer67, const sal_uInt8* pS) // note: in aBits1 there are 7 bits unused, // followed by another 16 unused bits - // In Version 8 koennen we can copy all border codes at once! - memcpy( pAktTC->rgbrc, pTc->rgbrcVer8, 4 * sizeof( WW8_BRC ) ); + pAktTC->rgbrc[ WW8_TOP ] = pTc->rgbrcVer8[ WW8_TOP ]; + pAktTC->rgbrc[ WW8_LEFT ] = pTc->rgbrcVer8[ WW8_LEFT ]; + pAktTC->rgbrc[ WW8_BOT ] = pTc->rgbrcVer8[ WW8_BOT ]; + pAktTC->rgbrc[ WW8_RIGHT ] = pTc->rgbrcVer8[ WW8_RIGHT ]; } } @@ -1191,7 +1193,7 @@ void WW8TabBandDesc::ReadDef(bool bVer67, const sal_uInt8* pS) } } -void WW8TabBandDesc::ProcessSprmTSetBRC(bool bVer67, const sal_uInt8* pParamsTSetBRC) +void WW8TabBandDesc::ProcessSprmTSetBRC(int nBrcVer, const sal_uInt8* pParamsTSetBRC) { if( pParamsTSetBRC && pTCs ) // set one or more cell border(s) { @@ -1211,98 +1213,43 @@ void WW8TabBandDesc::ProcessSprmTSetBRC(bool bVer67, const sal_uInt8* pParamsTSe bool bChangeTop = (nFlag & 0x01) ? true : false; WW8_TCell* pAktTC = pTCs + nitcFirst; - if( bVer67 ) - { - WW8_BRCVer6* pBRC = (WW8_BRCVer6*)(pParamsTSetBRC+3); - - for( int i = nitcFirst; i < nitcLim; ++i, ++pAktTC ) - { - if( bChangeTop ) - { - memcpy( pAktTC->rgbrc[ WW8_TOP ].aBits1, - pBRC->aBits1, - sizeof( SVBT16 ) ); - } - if( bChangeLeft ) - { - memcpy( pAktTC->rgbrc[ WW8_LEFT ].aBits1, - pBRC->aBits1, - sizeof( SVBT16 ) ); - } - if( bChangeBottom ) - { - memcpy( pAktTC->rgbrc[ WW8_BOT ].aBits1, - pBRC->aBits1, - sizeof( SVBT16 ) ); - } - if( bChangeRight ) - { - memcpy( pAktTC->rgbrc[ WW8_RIGHT].aBits1, - pBRC->aBits1, - sizeof( SVBT16 ) ); - } - } - } + WW8_BRCVer9 brcVer9; + if( nBrcVer == 6 ) + brcVer9 = WW8_BRC(*(WW8_BRCVer6*)(pParamsTSetBRC+3)); + else if( nBrcVer == 8 ) + brcVer9 = *(WW8_BRC*)(pParamsTSetBRC+3); else - { - WW8_BRC* pBRC = (WW8_BRC*)(pParamsTSetBRC+3); + brcVer9 = *(WW8_BRCVer9*)(pParamsTSetBRC+3); - for( int i = nitcFirst; i < nitcLim; ++i, ++pAktTC ) - { - if( bChangeTop ) - { - memcpy( pAktTC->rgbrc[ WW8_TOP ].aBits1, - pBRC->aBits1, - sizeof( SVBT16 ) ); - memcpy( pAktTC->rgbrc[ WW8_TOP ].aBits2, - pBRC->aBits2, - sizeof( SVBT16 ) ); - } - if( bChangeLeft ) - { - memcpy( pAktTC->rgbrc[ WW8_LEFT ].aBits1, - pBRC->aBits1, - sizeof( SVBT16 ) ); - memcpy( pAktTC->rgbrc[ WW8_LEFT ].aBits2, - pBRC->aBits2, - sizeof( SVBT16 ) ); - } - if( bChangeBottom ) - { - memcpy( pAktTC->rgbrc[ WW8_BOT ].aBits1, - pBRC->aBits1, - sizeof( SVBT16 ) ); - memcpy( pAktTC->rgbrc[ WW8_BOT ].aBits2, - pBRC->aBits2, - sizeof( SVBT16 ) ); - } - if( bChangeRight ) - { - memcpy( pAktTC->rgbrc[ WW8_RIGHT].aBits1, - pBRC->aBits1, - sizeof( SVBT16 ) ); - memcpy( pAktTC->rgbrc[ WW8_RIGHT].aBits2, - pBRC->aBits2, - sizeof( SVBT16 ) ); - } - } + for( int i = nitcFirst; i < nitcLim; ++i, ++pAktTC ) + { + if( bChangeTop ) + pAktTC->rgbrc[ WW8_TOP ] = brcVer9; + if( bChangeLeft ) + pAktTC->rgbrc[ WW8_LEFT ] = brcVer9; + if( bChangeBottom ) + pAktTC->rgbrc[ WW8_BOT ] = brcVer9; + if( bChangeRight ) + pAktTC->rgbrc[ WW8_RIGHT ] = brcVer9; } } } -void WW8TabBandDesc::ProcessSprmTTableBorders(bool bVer67, const sal_uInt8* pParams) +void WW8TabBandDesc::ProcessSprmTTableBorders(int nBrcVer, const sal_uInt8* pParams) { // sprmTTableBorders - if( bVer67 ) + if( nBrcVer == 6 ) { for( int i = 0; i < 6; ++i ) - { - aDefBrcs[i].aBits1[0] = pParams[ 2*i ]; - aDefBrcs[i].aBits1[1] = pParams[ 1+2*i ]; - } + aDefBrcs[i] = WW8_BRC( ((WW8_BRCVer6*)&pParams)[i] ); + } + else if ( nBrcVer == 8 ) + { + for( int i = 0; i < 6; ++i ) + aDefBrcs[i] = ((WW8_BRC*)&pParams)[i]; } - else // aDefBrcs = *(BRC(*)[6])pS; - memcpy( aDefBrcs, pParams, 24 ); + else + memcpy( aDefBrcs, pParams, sizeof( aDefBrcs ) ); } void WW8TabBandDesc::ProcessSprmTDxaCol(const sal_uInt8* pParamsTDxaCol) @@ -1606,8 +1553,8 @@ enum wwTableSprm sprmTTableWidth,sprmTTextFlow, sprmTFCantSplit, sprmTFCantSplit90,sprmTJc, sprmTFBiDi, sprmTDefTable, sprmTDyaRowHeight, sprmTDefTableShd, sprmTDxaLeft, sprmTSetBrc, - sprmTDxaCol, sprmTInsert, sprmTDelete, sprmTTableHeader, - sprmTDxaGapHalf, sprmTTableBorders, + sprmTSetBrc90, sprmTDxaCol, sprmTInsert, sprmTDelete, sprmTTableHeader, + sprmTDxaGapHalf, sprmTTableBorders, sprmTTableBorders90, sprmTDefTableNewShd, sprmTSpacing, sprmTNewSpacing }; @@ -1653,8 +1600,12 @@ wwTableSprm GetTableSprm(sal_uInt16 nId, ww::WordVersion eVer) return sprmTDefTableShd; case 0xD612: return sprmTDefTableNewShd; + case 0xD613: + return sprmTTableBorders90; case 0xD620: return sprmTSetBrc; + case 0xD62F: + return sprmTSetBrc90; case 0xD632: return sprmTSpacing; case 0xD634: @@ -1782,6 +1733,9 @@ WW8TabDesc::WW8TabDesc(SwWW8ImplReader* pIoClass, WW8_CP nStartCp) : bool bTabRowJustRead = false; const sal_uInt8* pShadeSprm = 0; const sal_uInt8* pNewShadeSprm = 0; + const sal_uInt8* pTableBorders = 0; + const sal_uInt8* pTableBorders90 = 0; + std::vector<const sal_uInt8*> aTSetBrcs, aTSetBrc90s; WW8_TablePos *pTabPos = 0; // search end of a tab row @@ -1828,7 +1782,10 @@ WW8TabDesc::WW8TabDesc(SwWW8ImplReader* pIoClass, WW8_CP nStartCp) : bClaimLineFmt = true; break; case sprmTTableBorders: - pNewBand->ProcessSprmTTableBorders(bOldVer, pParams); + pTableBorders = pParams; // process at end + break; + case sprmTTableBorders90: + pTableBorders90 = pParams; // process at end break; case sprmTTableHeader: if (!bRepeatedSprm) @@ -1875,7 +1832,10 @@ WW8TabDesc::WW8TabDesc(SwWW8ImplReader* pIoClass, WW8_CP nStartCp) : } break; case sprmTSetBrc: - pNewBand->ProcessSprmTSetBRC(bOldVer, pParams); + aTSetBrcs.push_back(pParams); // process at end + break; + case sprmTSetBrc90: + aTSetBrc90s.push_back(pParams); // process at end break; case sprmTDxaCol: pNewBand->ProcessSprmTDxaCol(pParams); @@ -1912,10 +1872,22 @@ WW8TabDesc::WW8TabDesc(SwWW8ImplReader* pIoClass, WW8_CP nStartCp) : if (bTabRowJustRead) { + // Some SPRMs need to be processed *after* ReadDef is called + // so they were saved up until here if (pShadeSprm) pNewBand->ReadShd(pShadeSprm); if (pNewShadeSprm) pNewBand->ReadNewShd(pNewShadeSprm, bOldVer); + if (pTableBorders90) + pNewBand->ProcessSprmTTableBorders(9, pTableBorders90); + else if (pTableBorders) + pNewBand->ProcessSprmTTableBorders(bOldVer ? 6 : 8, + pTableBorders); + std::vector<const sal_uInt8*>::const_iterator iter; + for (iter = aTSetBrcs.begin(); iter != aTSetBrcs.end(); ++iter) + pNewBand->ProcessSprmTSetBRC(bOldVer ? 6 : 8, *iter); + for (iter = aTSetBrc90s.begin(); iter != aTSetBrc90s.end(); ++iter) + pNewBand->ProcessSprmTSetBRC(9, *iter); } if( nTabeDxaNew < SHRT_MAX ) @@ -2150,7 +2122,7 @@ void WW8TabDesc::CalcDefaults() int i, j; for( i = 0; i < 4; i ++ ) { - if (pT->rgbrc[i].IsZeroed(pIo->bVer67)) + if (pT->rgbrc[i].brcType()==0) { // if shadow is set, its invalid j = i; @@ -2189,12 +2161,10 @@ void WW8TabDesc::CalcDefaults() dimensions, so in that case increase the table to include the extra width of the right margin. */ - if ( pIo->bVer67 ? - !(SVBT16ToShort(pR->pTCs[pR->nWwCols-1].rgbrc[3].aBits1) & 0x20) - : !(SVBT16ToShort(pR->pTCs[pR->nWwCols-1].rgbrc[3].aBits2) & 0x2000)) + if ( ! pR->pTCs[pR->nWwCols-1].rgbrc[3].fShadow() ) { short nThickness = pR->pTCs[pR->nWwCols-1].rgbrc[3]. - DetermineBorderProperties(pIo->bVer67); + DetermineBorderProperties(); pR->nCenter[pR->nWwCols] = pR->nCenter[pR->nWwCols] + nThickness; if (nThickness > nRightMaxThickness) nRightMaxThickness = nThickness; @@ -2207,12 +2177,10 @@ void WW8TabDesc::CalcDefaults() half is placed to the left of the nominal left side, and half to the right. */ - if ( pIo->bVer67 ? - !(SVBT16ToShort(pR->pTCs[0].rgbrc[1].aBits1) & 0x20) - : !(SVBT16ToShort(pR->pTCs[0].rgbrc[1].aBits2) & 0x2000)) + if ( ! pR->pTCs[0].rgbrc[1].fShadow() ) { short nThickness = pR->pTCs[0].rgbrc[1]. - DetermineBorderProperties(pIo->bVer67); + DetermineBorderProperties(); if (nThickness > nLeftMaxThickness) nLeftMaxThickness = nThickness; } diff --git a/sw/source/filter/ww8/ww8par6.cxx b/sw/source/filter/ww8/ww8par6.cxx index e8bb5e44fa82..4923053da591 100644 --- a/sw/source/filter/ww8/ww8par6.cxx +++ b/sw/source/filter/ww8/ww8par6.cxx @@ -109,7 +109,8 @@ using namespace nsHdFtFlags; #define MM_250 1417 // WW-Default fuer Hor. Seitenraender: 2.5 cm #define MM_200 1134 // WW-Default fuer u.Seitenrand: 2.0 cm -static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap, + +static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRCVer9* brc, WW8PLCFx_Cp_FKP* pPap, const WW8RStyle* pSty = 0, const WW8PLCFx_SEPX* pSep = 0); ColorData SwWW8ImplReader::GetCol(sal_uInt8 nIco) @@ -1191,20 +1192,26 @@ void SwWW8ImplReader::CopyPageDescHdFt(const SwPageDesc* pOrgPageDesc, // Hilfsroutinen fuer Grafiken und Apos und Tabellen -static bool _SetWW8_BRC(bool bVer67, WW8_BRC& rVar, const sal_uInt8* pS) +// Read BoRder Control structure +// nBrcVer should be set to the version of the BRC record being read (6, 8 or 9) +// This will be converted to the latest format (9). +static bool _SetWW8_BRC(int nBrcVer, WW8_BRCVer9& rVar, const sal_uInt8* pS) { + if( pS ) { - if( bVer67 ) - memcpy( rVar.aBits1, pS, sizeof( SVBT16 ) ); - else - rVar = *((WW8_BRC*)pS); + if ( nBrcVer == 9 ) + rVar = *(const WW8_BRCVer9*)pS; + else if( nBrcVer == 8 ) + rVar = *(const WW8_BRC*)pS; + else // nBrcVer == 6 + rVar = WW8_BRC(*(const WW8_BRCVer6*)pS); } return 0 != pS; } -static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPap, +static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRCVer9* brc, WW8PLCFx_Cp_FKP* pPap, const WW8RStyle* pSty, const WW8PLCFx_SEPX* pSep) { @@ -1223,7 +1230,7 @@ static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPa pSprm[0], pSprm[1], pSprm[2], pSprm[3] ) ) { for( int i = 0; i < 4; ++i ) - nBorder |= int(_SetWW8_BRC( bVer67, brc[ i ], pSprm[ i ] ))<<i; + nBorder |= int(_SetWW8_BRC( 8, brc[ i ], pSprm[ i ] ))<<i; } } } @@ -1235,17 +1242,40 @@ static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPa static const sal_uInt16 aVer8Ids[5] = { 0x6424, 0x6425, 0x6426, 0x6427, 0x6428 }; - const sal_uInt16* pIds = bVer67 ? aVer67Ids : aVer8Ids; + static const sal_uInt16 aVer9Ids[5] = + { 0xC64E, 0xC64F, 0xC650, 0xC651, 0xC652 }; if( pPap ) { - for( int i = 0; i < 5; ++i, ++pIds ) - nBorder |= int(_SetWW8_BRC( bVer67, brc[ i ], pPap->HasSprm( *pIds )))<<i; + if (bVer67) + { + for( int i = 0; i < 5; ++i ) + nBorder |= int(_SetWW8_BRC( 6 , brc[ i ], pPap->HasSprm( aVer67Ids[ i ] )))<<i; + } + else + { + for( int i = 0; i < 5; ++i ) + nBorder |= int(_SetWW8_BRC( 8 , brc[ i ], pPap->HasSprm( aVer8Ids[ i ] )))<<i; + // Version 9 BRCs if present will override version 8 + for( int i = 0; i < 5; ++i ) + nBorder |= int(_SetWW8_BRC( 9 , brc[ i ], pPap->HasSprm( aVer9Ids[ i ] )))<<i; + } } else if( pSty ) { - for( int i = 0; i < 5; ++i, ++pIds ) - nBorder |= int(_SetWW8_BRC( bVer67, brc[ i ], pSty->HasParaSprm( *pIds )))<<i; + if (bVer67) + { + for( int i = 0; i < 5; ++i ) + nBorder |= int(_SetWW8_BRC( 6 , brc[ i ], pSty->HasParaSprm( aVer67Ids[ i ] )))<<i; + } + else + { + for( int i = 0; i < 5; ++i ) + nBorder |= int(_SetWW8_BRC( 8 , brc[ i ], pSty->HasParaSprm( aVer8Ids[ i ] )))<<i; + // Version 9 BRCs if present will override version 8 + for( int i = 0; i < 5; ++i ) + nBorder |= int(_SetWW8_BRC( 9 , brc[ i ], pSty->HasParaSprm( aVer9Ids[ i ] )))<<i; + } } else { OSL_ENSURE( pSty || pPap, "WW8PLCFx_Cp_FKP and WW8RStyle " @@ -1256,9 +1286,17 @@ static sal_uInt8 lcl_ReadBorders(bool bVer67, WW8_BRC* brc, WW8PLCFx_Cp_FKP* pPa return nBorder; } -void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, sal_uInt8 nCol, short nIdx, - sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize=0) +void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, + sal_uInt32 cv, short nIdx, sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, + short *pSize=0) { + // LO cannot handle outset/inset (new in WW9 BRC) so fall back same as WW8 + if ( nIdx == 0x1A || nIdx == 0x1B ) + { + nIdx = (nIdx == 0x1A) ? 0x12 : 0x11; + cv = 0xc0c0c0; + } + ::editeng::SvxBorderStyle const eStyle( ::editeng::ConvertBorderStyleFromWord(nIdx)); @@ -1269,10 +1307,9 @@ void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, sal_uInt aLine.SetWidth(fConverted); //No AUTO for borders as yet, so if AUTO, use BLACK - if (nCol == 0) - nCol = 1; + ColorData col = (cv==0xff000000) ? COL_BLACK : msfilter::util::BGRToRGB(cv); - aLine.SetColor(SwWW8ImplReader::GetCol(nCol)); + aLine.SetColor(col); if (pSize) pSize[nWWIndex] = fConverted + nSpace; @@ -1282,64 +1319,32 @@ void GetLineIndex(SvxBoxItem &rBox, short nLineThickness, short nSpace, sal_uInt } -void Set1Border(bool bVer67, SvxBoxItem &rBox, const WW8_BRC& rBor, - sal_uInt16 nOOIndex, sal_uInt16 nWWIndex, short *pSize, const bool bIgnoreSpace) -{ - sal_uInt8 nCol; - short nSpace, nIdx; - short nLineThickness = rBor.DetermineBorderProperties(bVer67,&nSpace,&nCol, - &nIdx); - - GetLineIndex(rBox, nLineThickness, bIgnoreSpace ? 0 : nSpace, nCol, nIdx, nOOIndex, nWWIndex, pSize ); - -} - -static bool lcl_IsBorder(bool bVer67, const WW8_BRC* pbrc, bool bChkBtwn = false) +void Set1Border(SvxBoxItem &rBox, const WW8_BRCVer9& rBor, sal_uInt16 nOOIndex, + sal_uInt16 nWWIndex, short *pSize, const bool bIgnoreSpace) { - 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]); -} + short nSpace; + short nLineThickness = rBor.DetermineBorderProperties(&nSpace); -bool SwWW8ImplReader::IsBorder(const WW8_BRC* pbrc, bool bChkBtwn) const -{ - return lcl_IsBorder(bVer67, pbrc, bChkBtwn); -} + GetLineIndex(rBox, nLineThickness, bIgnoreSpace ? 0 : nSpace, + rBor.cv(), rBor.brcType(), nOOIndex, nWWIndex, pSize ); -bool WW8_BRC::IsEmpty(bool bVer67) const -{ - return (IsBlank() || IsZeroed(bVer67)); } -bool WW8_BRC::IsBlank() const +static bool lcl_IsBorder(const WW8_BRCVer9* pbrc, bool bChkBtwn = false) { - return (aBits1[0] == 0xff && aBits1[1] == 0xff); + return pbrc[WW8_TOP ].brcType() || // brcType != 0 + pbrc[WW8_LEFT ].brcType() || + pbrc[WW8_BOT ].brcType() || + pbrc[WW8_RIGHT].brcType() || + (bChkBtwn && pbrc[WW8_BETW ].brcType()); } -bool WW8_BRC::IsZeroed(bool bVer67) const +bool SwWW8ImplReader::IsBorder(const WW8_BRCVer9* pbrc, bool bChkBtwn) const { - return (!(bVer67 ? (aBits1[0] & 0x001f) : aBits1[1])); + return lcl_IsBorder(pbrc, bChkBtwn); } -bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc, +bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRCVer9* pbrc, short *pSizeArray, sal_uInt8 nSetBorders) const { bool bChange = false; @@ -1355,10 +1360,10 @@ bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc, for( int i = 0, nEnd = 8; i < nEnd; i += 2 ) { // ungueltige Borders ausfiltern - const WW8_BRC& rB = pbrc[ aIdArr[ i ] ]; - if( !rB.IsEmpty(bVer67)) + const WW8_BRCVer9& rB = pbrc[ aIdArr[ i ] ]; + if( !rB.isNil() && rB.brcType() ) { - Set1Border(bVer67, rBox, rB, aIdArr[i+1], aIdArr[i], pSizeArray, false); + Set1Border(rBox, rB, aIdArr[i+1], aIdArr[i], pSizeArray, false); bChange = true; } else if ( nSetBorders & (1 << aIdArr[i]) ) @@ -1381,18 +1386,14 @@ bool SwWW8ImplReader::SetBorder(SvxBoxItem& rBox, const WW8_BRC* pbrc, } bool SwWW8ImplReader::SetShadow(SvxShadowItem& rShadow, const short *pSizeArray, - const WW8_BRC& aRightBrc) const + const WW8_BRCVer9& aRightBrc) const { - bool bRet = ( - ( bVer67 ? (aRightBrc.aBits1[ 0 ] & 0x20 ) - : (aRightBrc.aBits2[ 1 ] & 0x20 ) ) - && (pSizeArray && pSizeArray[WW8_RIGHT]) - ); + bool bRet = aRightBrc.fShadow() && pSizeArray && pSizeArray[WW8_RIGHT]; if (bRet) { rShadow.SetColor(Color(COL_BLACK)); //i120718 - short nVal = aRightBrc.DetermineBorderProperties(bVer67); + short nVal = aRightBrc.DetermineBorderProperties(); //End if (nVal < 0x10) nVal = 0x10; @@ -1403,28 +1404,17 @@ bool SwWW8ImplReader::SetShadow(SvxShadowItem& rShadow, const short *pSizeArray, return bRet; } -void SwWW8ImplReader::GetBorderDistance(const WW8_BRC* pbrc, +void SwWW8ImplReader::GetBorderDistance(const WW8_BRCVer9* 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 ); - } + rInnerDist = Rectangle( pbrc[ 1 ].dptSpace() * 20, + pbrc[ 0 ].dptSpace() * 20, + pbrc[ 3 ].dptSpace() * 20, + pbrc[ 2 ].dptSpace() * 20 ); } bool SwWW8ImplReader::SetFlyBordersShadow(SfxItemSet& rFlySet, - const WW8_BRC *pbrc, short *pSizeArray) const + const WW8_BRCVer9 *pbrc, short *pSizeArray) const { bool bShadowed = false; if (IsBorder(pbrc)) @@ -1567,7 +1557,7 @@ void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8PLCFx_Cp_FKP* pPap) } if( ::lcl_ReadBorders( bVer67, brc, pPap )) // Umrandung - bBorderLines = ::lcl_IsBorder( bVer67, brc ); + bBorderLines = ::lcl_IsBorder( brc ); /* #i8798# @@ -1685,7 +1675,7 @@ void WW8FlyPara::Read(sal_uInt8 nOrigSp29, WW8RStyle* pStyle) } if (::lcl_ReadBorders(bVer67, brc, 0, pStyle)) // Umrandung - bBorderLines = ::lcl_IsBorder(bVer67, brc); + bBorderLines = ::lcl_IsBorder(brc); /* #i8798# @@ -1882,16 +1872,16 @@ WW8SwFlyPara::WW8SwFlyPara( SwPaM& rPaM, sal_Int16 nLeBorderMgn( 0L ); if ( !bAutoWidth ) { - sal_Int16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67, - &nLeBorderMgn); + WW8_BRCVer9 &rBrc = rWW.brc[WW8_LEFT]; + sal_Int16 nTemp = rBrc.DetermineBorderProperties(&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); + WW8_BRCVer9 &rBrc = rWW.brc[WW8_RIGHT]; + sal_Int16 nTemp = rBrc.DetermineBorderProperties(&nRiBorderMgn); nRiBorderMgn = nRiBorderMgn + nTemp; } if ( !bAutoWidth && eHAlign == text::HoriOrientation::LEFT && eHRel == text::RelOrientation::PAGE_FRAME ) @@ -1943,9 +1933,9 @@ WW8SwFlyPara::WW8SwFlyPara( SwPaM& rPaM, Word has a curious bug where the offset stored do not take into account the internal distance from the corner both */ + WW8_BRCVer9 &rBrc = rWW.brc[WW8_LEFT]; sal_Int16 nLeLMgn = 0; - sal_Int16 nTemp = rWW.brc[WW8_LEFT].DetermineBorderProperties(rWW.bVer67, - &nLeLMgn); + sal_Int16 nTemp = rBrc.DetermineBorderProperties(&nLeLMgn); nLeLMgn = nLeLMgn + nTemp; if (nLeLMgn) @@ -2014,7 +2004,7 @@ WW8FlySet::WW8FlySet(SwWW8ImplReader& rReader, const WW8FlyPara* pFW, Put( aSurround ); short aSizeArray[5]={0}; - rReader.SetFlyBordersShadow(*this,(const WW8_BRC*)pFW->brc,&aSizeArray[0]); + rReader.SetFlyBordersShadow(*this,pFW->brc,&aSizeArray[0]); // der 5. Parameter ist immer 0, daher geht beim Cast nix verloren @@ -2058,7 +2048,10 @@ WW8FlySet::WW8FlySet( SwWW8ImplReader& rReader, const SwPaM* pPaM, 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])) + WW8_BRCVer9 brcVer9[4]; + for (int i = 0; i < 4; i++) + brcVer9[i] = rPic.rgbrc[i]; + if (rReader.SetFlyBordersShadow( *this, brcVer9, &aSizeArray[0])) { Put(SvxLRSpaceItem( aSizeArray[WW8_LEFT], 0, 0, 0, RES_LR_SPACE ) ); Put(SvxULSpaceItem( aSizeArray[WW8_TOP], 0, RES_UL_SPACE )); @@ -4672,7 +4665,7 @@ void SwWW8ImplReader::Read_Border(sal_uInt16 , const sal_uInt8*, short nLen) // CtrlStack und wieder runter bHasBorder = true; - WW8_BRC5 aBrcs; // Top, Left, Bottom, Right, Between + WW8_BRCVer9_5 aBrcs; // Top, Left, Bottom, Right, Between sal_uInt8 nBorder; if( pAktColl ) @@ -4728,11 +4721,11 @@ void SwWW8ImplReader::Read_Border(sal_uInt16 , const sal_uInt8*, short nLen) } } -void SwWW8ImplReader::Read_CharBorder(sal_uInt16 /*nId*/, const sal_uInt8* pData, short nLen ) +void SwWW8ImplReader::Read_CharBorder(sal_uInt16 nId, const sal_uInt8* pData, short nLen ) { //Ignore this old border type - if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0xCA72)) - return; + //if (!bVer67 && pPlcxMan && pPlcxMan->GetChpPLCF()->HasSprm(0xCA72)) + // return; if( nLen < 0 ) { @@ -4747,13 +4740,15 @@ void SwWW8ImplReader::Read_CharBorder(sal_uInt16 /*nId*/, const sal_uInt8* pData { SvxBoxItem aBoxItem(RES_CHRATR_BOX); aBoxItem = *pBox; - WW8_BRC aBrc; - _SetWW8_BRC(bVer67, aBrc, pData); + WW8_BRCVer9 aBrc; + int nBrcVer = (nId == NS_sprm::LN_CBorder) ? 9 : (bVer67 ? 6 : 8); + + _SetWW8_BRC(nBrcVer, aBrc, pData); - Set1Border(bVer67, aBoxItem, aBrc, BOX_LINE_TOP, 0, 0, true); - Set1Border(bVer67, aBoxItem, aBrc, BOX_LINE_BOTTOM, 0, 0, true); - Set1Border(bVer67, aBoxItem, aBrc, BOX_LINE_LEFT, 0, 0, true); - Set1Border(bVer67, aBoxItem, aBrc, BOX_LINE_RIGHT, 0, 0, true); + Set1Border(aBoxItem, aBrc, BOX_LINE_TOP, 0, 0, true); + Set1Border(aBoxItem, aBrc, BOX_LINE_BOTTOM, 0, 0, true); + Set1Border(aBoxItem, aBrc, BOX_LINE_LEFT, 0, 0, true); + Set1Border(aBoxItem, aBrc, BOX_LINE_RIGHT, 0, 0, true); NewAttr( aBoxItem ); short aSizeArray[WW8_RIGHT+1]={0}; aSizeArray[WW8_RIGHT] = 1; @@ -5845,6 +5840,7 @@ const wwSprmDispatcher *GetWW8SprmDispatcher() {NS_sprm::LN_CDttmRMarkDel, 0}, //chp.dttmRMarkDel;DTTM;long; {0x6865, &SwWW8ImplReader::Read_CharBorder}, //"sprmCBrc" chp.brc;BRC;long; + {0xca72, &SwWW8ImplReader::Read_CharBorder}, //"sprmCBorder" chp.brc;BRC;long; {0x4866, &SwWW8ImplReader::Read_CharShadow}, //"sprmCShd" chp.shd;SHD;short; {0x4867, 0}, //"sprmCIdslRMarkDel" //chp.idslRMReasonDel;an index @@ -6067,10 +6063,11 @@ const wwSprmDispatcher *GetWW8SprmDispatcher() {0xD634, 0}, //undocumented {0xD632, 0}, //undocumented {0xD238, 0}, //undocumented sep - {0xC64E, 0}, //undocumented - {0xC64F, 0}, //undocumented - {0xC650, 0}, //undocumented - {0xC651, 0}, //undocumented + {0xC64E, &SwWW8ImplReader::Read_Border}, //"sprmPBorderTop" + {0xC64F, &SwWW8ImplReader::Read_Border}, //"sprmPBorderLeft" + {0xC650, &SwWW8ImplReader::Read_Border}, //"sprmPBorderBottom" + {0xC651, &SwWW8ImplReader::Read_Border}, //"sprmPBorderRight" + {0xC652, &SwWW8ImplReader::Read_Border}, //"sprmPBorderBetween" {0xF661, 0}, //undocumented {0x4873, &SwWW8ImplReader::Read_Language}, //"sprmCRgLid0" chp.rglid[0]; //LID: for non-Far East text; diff --git a/sw/source/filter/ww8/ww8scan.cxx b/sw/source/filter/ww8/ww8scan.cxx index 646c4eb53ea1..7354ab01b593 100644 --- a/sw/source/filter/ww8/ww8scan.cxx +++ b/sw/source/filter/ww8/ww8scan.cxx @@ -18,6 +18,7 @@ */ #include "ww8scan.hxx" +#include "ww8par.hxx" #include <functional> #include <algorithm> @@ -739,10 +740,11 @@ const wwSprmSearcher *wwSprmParser::GetWW8SprmSearcher() {0xD632, 0, L_VAR}, // undocumented {0xD634, 0, L_VAR}, // undocumented {0xD238, 0, L_VAR}, // undocumented sep - {0xC64E, 0, L_VAR}, // undocumented - {0xC64F, 0, L_VAR}, // undocumented - {0xC650, 0, L_VAR}, // undocumented - {0xC651, 0, L_VAR}, // undocumented + {0xC64E, 0, L_VAR}, // "sprmPBorderTop" + {0xC64F, 0, L_VAR}, // "sprmPBorderLeft" + {0xC650, 0, L_VAR}, // "sprmPBorderBottom" + {0xC651, 0, L_VAR}, // "sprmPBorderRight" + {0xC652, 0, L_VAR}, // "sprmPBorderBetween" {0xF661, 3, L_FIX}, // undocumented {0x4873, 2, L_FIX}, // "sprmCRgLid0" chp.rglid[0];LID: for non-FE text {0x4874, 2, L_FIX}, // "sprmCRgLid1" chp.rglid[1];LID: for Far East text @@ -1256,8 +1258,64 @@ WW8_CP WW8PLCFx_PCD::AktPieceStartFc2Cp( WW8_FC nStartPos ) // Helper routines for all -short WW8_BRC::DetermineBorderProperties(bool bVer67, short *pSpace, - sal_uInt8 *pCol, short *pIdx) const +// Convert BRC from WW6 to WW8 format +WW8_BRC::WW8_BRC(const WW8_BRCVer6& brcVer6) +{ + sal_uInt8 _dptLineWidth = brcVer6.dxpLineWidth(), + _brcType = brcVer6.brcType(); + + if (_dptLineWidth > 5) // this signifies dashed(6) or dotted(7) line + { + _brcType = _dptLineWidth; + _dptLineWidth = 1; + } + _dptLineWidth *= 6; // convert units from 0.75pt to 1/8pt + + *this = WW8_BRC(_dptLineWidth, _brcType, brcVer6.ico(), brcVer6.dxpSpace(), + brcVer6.fShadow(), false); +} + +// Convert BRC from WW8 to WW6 format +WW8_BRCVer6::WW8_BRCVer6(const WW8_BRC& brcVer8) +{ + sal_uInt8 _brcType = brcVer8.brcType(); + sal_uInt8 _dxpLineWidth = std::max(brcVer8.dptLineWidth() / 6, 7); + if (_brcType == 5 || _brcType == 6 ) + { + _dxpLineWidth = _brcType; + _brcType = 1; + } + else if (_brcType > 3) + { + _brcType = 1; + } + *this = WW8_BRCVer6(_dxpLineWidth, _brcType, brcVer8.ico(), + brcVer8.dptSpace(), brcVer8.fShadow()); +} + +// Convert BRC from WW8 to WW9 format +WW8_BRCVer9::WW8_BRCVer9(const WW8_BRC& brcVer8) +{ + if (brcVer8.isNil()) { + UInt32ToSVBT32(0, aBits1); + UInt32ToSVBT32(0xffffffff, aBits2); + } + else + { + sal_uInt32 _cv = brcVer8.ico() == 0 ? 0xff000000 // "auto" colour + : wwUtility::RGBToBGR(SwWW8ImplReader::GetCol(brcVer8.ico())); + *this = WW8_BRCVer9(_cv, brcVer8.dptLineWidth(), brcVer8.brcType(), + brcVer8.dptSpace(), brcVer8.fShadow(), brcVer8.fFrame()); + } +} + +short WW8_BRC::DetermineBorderProperties(short *pSpace) const +{ + WW8_BRCVer9 brcVer9(*this); + return brcVer9.DetermineBorderProperties(pSpace); +} + +short WW8_BRCVer9::DetermineBorderProperties(short *pSpace) const { /* Word does not factor the width of the border into the width/height @@ -1266,89 +1324,61 @@ short WW8_BRC::DetermineBorderProperties(bool bVer67, short *pSpace, our calculations */ short nMSTotalWidth; - sal_uInt8 nCol; - short nIdx,nSpace; - if( bVer67 ) - { - sal_uInt16 aBrc1 = SVBT16ToShort(aBits1); - nCol = static_cast< sal_uInt8 >((aBrc1 >> 6) & 0x1f); // aBor.ico - nSpace = (aBrc1 & 0xF800) >> 11; - - nMSTotalWidth = aBrc1 & 0x07; - nIdx = (aBrc1 & 0x18) >> 3; - //Dashed/Dotted unsets double/thick - if (nMSTotalWidth > 5) - { - nIdx = nMSTotalWidth; - nMSTotalWidth=1; - } - nMSTotalWidth = nMSTotalWidth * nIdx * 15; - } - else - { - nIdx = aBits1[1]; - nCol = aBits2[0]; // aBor.ico - nSpace = aBits2[1] & 0x1F; //space between line and object - //Specification in 8ths of a point, 1 Point = 20 Twips, so by 2.5 - nMSTotalWidth = aBits1[ 0 ] * 20 / 8; + //Specification in 8ths of a point, 1 Point = 20 Twips, so by 2.5 + nMSTotalWidth = (short)dptLineWidth() * 20 / 8; - //Figure out the real size of the border according to word - switch (nIdx) - { - //Note that codes over 25 are undocumented, and I can't create - //these 4 here in the wild. - case 2: - case 4: - case 5: - case 22: - OSL_FAIL("Can't create these from the menus, please report"); - default: - case 23: //Only 3pt in the menus, but honours the size setting. - break; - case 10: - /* - triple line is five times the width of an ordinary line, - except that the smallest 1/4 point size appears to have - exactly the same total border width as a 3/4 point size - ordinary line, i.e. three times the nominal line width. The - second smallest 1/2 point size appears to have exactly the - total border width as a 2 1/4 border, i.e 4.5 times the size. - */ - if (nMSTotalWidth == 5) - nMSTotalWidth*=3; - else if (nMSTotalWidth == 10) - nMSTotalWidth = nMSTotalWidth*9/2; - else - nMSTotalWidth*=5; - break; - case 20: - /* - wave, the dimensions appear to be created by the drawing of - the wave, so we have only two possibilites in the menus, 3/4 - point is equal to solid 3 point. This calculation seems to - match well to results. - */ - nMSTotalWidth +=45; - break; - case 21: - /* - double wave, the dimensions appear to be created by the - drawing of the wave, so we have only one possibilites in the - menus, that of 3/4 point is equal to solid 3 point. This - calculation seems to match well to results. - */ - nMSTotalWidth += 45*2; - break; - } + //Figure out the real size of the border according to word + switch (brcType()) + { + //Note that codes over 25 are undocumented, and I can't create + //these 4 here in the wild. + case 2: + case 4: + case 5: + case 22: + OSL_FAIL("Can't create these from the menus, please report"); + default: + case 23: //Only 3pt in the menus, but honours the size setting. + break; + case 10: + /* + triple line is five times the width of an ordinary line, + except that the smallest 1/4 point size appears to have + exactly the same total border width as a 3/4 point size + ordinary line, i.e. three times the nominal line width. The + second smallest 1/2 point size appears to have exactly the + total border width as a 2 1/4 border, i.e 4.5 times the size. + */ + if (nMSTotalWidth == 5) + nMSTotalWidth*=3; + else if (nMSTotalWidth == 10) + nMSTotalWidth = nMSTotalWidth*9/2; + else + nMSTotalWidth*=5; + break; + case 20: + /* + wave, the dimensions appear to be created by the drawing of + the wave, so we have only two possibilites in the menus, 3/4 + point is equal to solid 3 point. This calculation seems to + match well to results. + */ + nMSTotalWidth +=45; + break; + case 21: + /* + double wave, the dimensions appear to be created by the + drawing of the wave, so we have only one possibilites in the + menus, that of 3/4 point is equal to solid 3 point. This + calculation seems to match well to results. + */ + nMSTotalWidth += 45*2; + break; } - if (pIdx) - *pIdx = nIdx; if (pSpace) - *pSpace = nSpace*20; - if (pCol) - *pCol = nCol; + *pSpace = (short)dptSpace() * 20; // convert from points to twips return nMSTotalWidth; } diff --git a/sw/source/filter/ww8/ww8struc.hxx b/sw/source/filter/ww8/ww8struc.hxx index 52d68fc51a98..2fe7c578e229 100644 --- a/sw/source/filter/ww8/ww8struc.hxx +++ b/sw/source/filter/ww8/ww8struc.hxx @@ -226,7 +226,7 @@ struct WW8_FFN : public WW8_FFN_BASE // font does not exist on this system. }; -struct WW8_BRCVer6 // alter Border Code +struct WW8_BRCVer6 // BoRder Code (WW6 version) { SVBT16 aBits1; // sal_uInt16 dxpLineWidth : 3;// 0007 When dxpLineWidth is 0, 1, 2, 3, 4, or 5, this field is the width of @@ -238,36 +238,135 @@ struct WW8_BRCVer6 // alter Border Code // sal_uInt16 ico : 5; // 07C0 color code (see chp.ico) // sal_uInt16 dxpSpace : 5; // F800 width of space to maintain between border and text within border. // Must be 0 when BRC is a substructure of the TC. Stored in points for Windows. + sal_uInt8 dxpLineWidth() const + { return aBits1[0] & 0x07; } + sal_uInt8 brcType() const + { return (aBits1[0] & 0x18) >> 3; } + bool fShadow() const + { return !!(aBits1[0] & 0x20); } + sal_uInt8 ico() const + { return ((aBits1[0] & 0xc0) >> 6) | ((aBits1[1] & 0x07) << 2); } + sal_uInt8 dxpSpace() const + { return aBits1[1] >> 3; } + + WW8_BRCVer6(sal_uInt8 _dxpLineWidth, sal_uInt8 _brcType, sal_uInt8 _ico, + sal_uInt8 _dxpSpace, bool _fShadow) + { + assert(_dxpSpace < 0x20); + assert(_brcType <= 3); + assert(_ico < 32); + aBits1[0] = _dxpLineWidth | (_brcType << 3) | ((sal_uInt8)_fShadow << 5) + | ((_ico << 6) & 0xc0); + aBits1[1] = (_ico >> 2) | (_dxpSpace << 3); + } + // Convert BRC from WW8 to WW6 format + WW8_BRCVer6(const class WW8_BRC& brcVer8); }; -class WW8_BRC // Border Code +struct WW8_BRC // BoRder Code (WW8 version) +// Documented at http://msdn.microsoft.com/en-us/library/dd952599.aspx { -public: SVBT16 aBits1; SVBT16 aBits2; -// sal_uInt16 dxpLineWidth : 3;// 0007 When dxpLineWidth is 0, 1, 2, 3, 4, or 5, this field is the width of - // a single line of border in units of 0.75 points - // Must be nonzero when brcType is nonzero. - // 6 == dotted, 7 == dashed. -// sal_uInt16 brcType : 2; // 0018 border type code: 0 == none, 1 == single, 2 == thick, 3 == double -// sal_uInt16 fShadow : 1; // 0020 when 1, border is drawn with shadow. Must be 0 when BRC is a substructure of the TC -// sal_uInt16 ico : 5; // 07C0 color code (see chp.ico) -// sal_uInt16 dxpSpace : 5; // F800 width of space to maintain between border and text within border. - // Must be 0 when BRC is a substructure of the TC. Stored in points for Windows. +// sal_uInt8 dptLineWidth; +// sal_uInt8 brcType; +// sal_uInt8 ico; +// sal_uInt8 dptSpace : 5 +// bool fShadow : 1; +// bool fFrame : 1; +// bool fReserved : 1; WW8_BRC() { memset(aBits1, 0, sizeof(aBits1)); memset(aBits2, 0, sizeof(aBits2)); } - short DetermineBorderProperties (bool bVer67, short *pSpace=0, - sal_uInt8 *pCol=0, short *pIdx=0) const; - bool IsEmpty(bool bVer67) const; - bool IsZeroed(bool bVer67) const; - bool IsBlank() const; + + sal_uInt8 dptLineWidth() const // border line width (1/8pt) + { return aBits1[0]; } + sal_uInt8 brcType() const // border type (eg single, double, dotted) + { return aBits1[1]; } + sal_uInt8 ico() const // colour index, 1-17 or 0=auto + { return aBits2[0]; } + sal_uInt8 dptSpace() const // space between text & border (pt) + { return aBits2[1] & 0x1f; } + bool fShadow() const // shadow effect + { return !!(aBits2[1] & 0x20); } + bool fFrame() const // 3D frame effect + { return !!(aBits2[1] & 0x40); } + bool isNil() const // nil = no border + { return aBits1[0] == 0xff && aBits1[1] == 0xff; } + + WW8_BRC(sal_uInt8 _dptLineWidth, sal_uInt8 _brcType, sal_uInt8 _ico, + sal_uInt8 _dptSpace, bool _fShadow, bool _fFrame) + { + assert(_dptSpace < 0x20); + aBits1[0] = _dptLineWidth; + aBits1[1] = _brcType; + aBits2[0] = _ico; + aBits2[1] = _dptSpace | ((sal_uInt8)_fShadow << 5) + | ((sal_uInt8)_fFrame << 6); + } + // Convert BRC from WW6 to WW8 format + WW8_BRC(const WW8_BRCVer6& brcVer6); + + // Returns LO border width in twips=1/20pt, taking into account brcType + short DetermineBorderProperties(short *pSpace=0) const; }; typedef WW8_BRC WW8_BRC5[5]; // 5 * Border Code +struct WW8_BRCVer9 // BoRder Code (WW9 version) +// Documented at http://msdn.microsoft.com/en-us/library/dd907496.aspx +{ + SVBT32 aBits1; // border colour (RGB) + SVBT32 aBits2; +// sal_uInt8 dptLineWidth; // border line width (1/8pt) +// sal_uInt8 brcType; // border type (eg single, double, dotted) +// sal_uInt8 dptSpace : 5; // space between text & border (pt) +// bool fShadow : 1; // border has shadow effect +// bool fFrame : 1; // border has 3D effect +// sal_uInt16 fReserved : 9; // unused + WW8_BRCVer9() + { + memset(aBits1, 0, sizeof(aBits1)); + memset(aBits2, 0, sizeof(aBits2)); + } + + sal_uInt32 cv() const // colour value (BGR) + { return SVBT32ToUInt32(aBits1); } + sal_uInt8 dptLineWidth() const // border line width (1/8pt) + { return aBits2[0]; } + sal_uInt8 brcType() const // border type (eg single, double, dotted) + { return aBits2[1]; } + sal_uInt8 dptSpace() const // space between text & border (pt) + { return aBits2[2] & 0x1f; } + bool fShadow() const // shadow effect + { return !!(aBits2[2] & 0x20); } + bool fFrame() const // 3D frame effect + { return !!(aBits2[2] & 0x40); } + bool isNil() const // nil = no border + { return SVBT32ToUInt32(aBits2) == 0xffffffff; } + + WW8_BRCVer9(sal_uInt32 _cv, sal_uInt8 _dptLineWidth, sal_uInt8 _brcType, + sal_uInt8 _dptSpace, bool _fShadow, bool _fFrame) + { + assert(_dptSpace < 0x20); + UInt32ToSVBT32(_cv, aBits1); + aBits2[0] = _dptLineWidth; + aBits2[1] = _brcType; + aBits2[2] = _dptSpace | ((sal_uInt8)_fShadow << 5) + | ((sal_uInt8)_fFrame << 6); + aBits2[3] = 0; + } + // Convert BRC from WW8 to WW9 format + WW8_BRCVer9(const WW8_BRC& brcVer8); + + // Returns LO border width in twips=1/20pt, taking into account brcType + short DetermineBorderProperties(short *pSpace=0) const; +}; + +typedef WW8_BRCVer9 WW8_BRCVer9_5[5]; // 5 * Border Code + enum BRC_Sides { WW8_TOP = 0, WW8_LEFT = 1, WW8_BOT = 2, WW8_RIGHT = 3, WW8_BETW = 4 @@ -444,7 +543,7 @@ struct WW8_TCell // hiermit wird weitergearbeitet (entspricht weitestgehend d // 2 bottom sal_uInt16 fUnused : 7;// reserved - nicht loeschen: macht das sal_uInt16 voll !! - WW8_BRC rgbrc[4]; // border codes + WW8_BRCVer9 rgbrc[4]; // border codes //notational convenience for referring to brcTop, brcLeft, etc fields. // BRC brcTop; // specification of the top border of a table cell // BRC brcLeft; // specification of left border of table row |